diff --git a/auth/credentials.py b/auth/credentials.py index 951769e8..9045b7a4 100644 --- a/auth/credentials.py +++ b/auth/credentials.py @@ -34,6 +34,7 @@ class AuthCredentials(BaseModel): class AuthUser(BaseModel): user_id: Optional[int] + username: Optional[str] @property def is_authenticated(self) -> bool: diff --git a/auth/identity.py b/auth/identity.py index bd343e6e..e4b78040 100644 --- a/auth/identity.py +++ b/auth/identity.py @@ -89,7 +89,7 @@ class Identity: try: print('[auth.identity] using one time token') payload = JWTCodec.decode(token) - if not await TokenStorage.exist(f"{payload.user_id}-{token}"): + if not await TokenStorage.exist(f"{payload.user_id}-{payload.username}-{token}"): # raise InvalidToken("Login token has expired, please login again") return { "error": "Token has expired" diff --git a/auth/jwtcodec.py b/auth/jwtcodec.py index 387df057..7f176e58 100644 --- a/auth/jwtcodec.py +++ b/auth/jwtcodec.py @@ -22,6 +22,7 @@ class JWTCodec: @staticmethod def decode(token: str, verify_exp: bool = True) -> TokenPayload: + r = None try: payload = jwt.decode( token, @@ -34,13 +35,13 @@ class JWTCodec: issuer="discours" ) r = TokenPayload(**payload) - # print('[auth.jwtcodec] debug payload %r' % r) + print('[auth.jwtcodec] debug token %r' % r) return r except jwt.InvalidIssuedAtError: - print('[auth.jwtcodec] invalid issued at: %r' % r) + print('[auth.jwtcodec] invalid issued at: %r' % payload) raise ExpiredToken('check token issued time') except jwt.ExpiredSignatureError: - print('[auth.jwtcodec] expired signature %r' % r) + print('[auth.jwtcodec] expired signature %r' % payload) raise ExpiredToken('check token lifetime') except jwt.InvalidTokenError: raise InvalidToken('token is not valid') diff --git a/auth/tokenstorage.py b/auth/tokenstorage.py index 5c1b5b2d..c61aa848 100644 --- a/auth/tokenstorage.py +++ b/auth/tokenstorage.py @@ -28,15 +28,15 @@ class SessionToken: raise e @classmethod - async def get(cls, uid, token): - return await TokenStorage.get(f"{uid}-{token}") + async def get(cls, payload, token): + return await TokenStorage.get(f"{payload.user_id}-{payload.username}-{token}") class TokenStorage: @staticmethod async def get(token_key): print('[tokenstorage.get] ' + token_key) - # 2041-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyMDQxLCJ1c2VybmFtZSI6ImFudG9uLnJld2luK3Rlc3QtbG9hZGNoYXRAZ21haWwuY29tIiwiZXhwIjoxNjcxNzgwNjE2LCJpYXQiOjE2NjkxODg2MTYsImlzcyI6ImRpc2NvdXJzIn0.Nml4oV6iMjMmc6xwM7lTKEZJKBXvJFEIZ-Up1C1rITQ + # 2041-user@domain.zn-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyMDQxLCJ1c2VybmFtZSI6ImFudG9uLnJld2luK3Rlc3QtbG9hZGNoYXRAZ21haWwuY29tIiwiZXhwIjoxNjcxNzgwNjE2LCJpYXQiOjE2NjkxODg2MTYsImlzcyI6ImRpc2NvdXJzIn0.Nml4oV6iMjMmc6xwM7lTKEZJKBXvJFEIZ-Up1C1rITQ return await redis.execute("GET", token_key) @staticmethod @@ -44,7 +44,7 @@ class TokenStorage: life_span = ONETIME_TOKEN_LIFE_SPAN exp = datetime.now(tz=timezone.utc) + timedelta(seconds=life_span) one_time_token = JWTCodec.encode(user, exp) - await save(f"{user.id}-{one_time_token}", life_span) + await save(f"{user.id}-{user.username}-{one_time_token}", life_span) return one_time_token @staticmethod @@ -52,7 +52,7 @@ class TokenStorage: life_span = SESSION_TOKEN_LIFE_SPAN exp = datetime.now(tz=timezone.utc) + timedelta(seconds=life_span) session_token = JWTCodec.encode(user, exp) - await save(f"{user.id}-{session_token}", life_span) + await save(f"{user.id}-{user.username}-{session_token}", life_span) return session_token @staticmethod @@ -64,7 +64,7 @@ class TokenStorage: except: # noqa pass else: - await redis.execute("DEL", f"{payload.user_id}-{token}") + await redis.execute("DEL", f"{payload.user_id}-{payload.username}-{token}") return True @staticmethod diff --git a/resolvers/auth.py b/resolvers/auth.py index 7734df04..6108a827 100644 --- a/resolvers/auth.py +++ b/resolvers/auth.py @@ -47,7 +47,7 @@ async def confirm_email(_, info, token): print('[resolvers.auth] confirm email by token') payload = JWTCodec.decode(token) user_id = payload.user_id - await TokenStorage.get(f"{user_id}-{token}") + await TokenStorage.get(f"{user_id}-{payload.username}-{token}") with local_session() as session: user = session.query(User).where(User.id == user_id).first() session_token = await TokenStorage.create_session(user)