fix-session

This commit is contained in:
tonyrewin 2023-01-31 09:57:35 +03:00
parent af3d3b08ad
commit a01371a670
5 changed files with 13 additions and 11 deletions

View File

@ -34,6 +34,7 @@ class AuthCredentials(BaseModel):
class AuthUser(BaseModel): class AuthUser(BaseModel):
user_id: Optional[int] user_id: Optional[int]
username: Optional[str]
@property @property
def is_authenticated(self) -> bool: def is_authenticated(self) -> bool:

View File

@ -89,7 +89,7 @@ class Identity:
try: try:
print('[auth.identity] using one time token') print('[auth.identity] using one time token')
payload = JWTCodec.decode(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") # raise InvalidToken("Login token has expired, please login again")
return { return {
"error": "Token has expired" "error": "Token has expired"

View File

@ -22,6 +22,7 @@ class JWTCodec:
@staticmethod @staticmethod
def decode(token: str, verify_exp: bool = True) -> TokenPayload: def decode(token: str, verify_exp: bool = True) -> TokenPayload:
r = None
try: try:
payload = jwt.decode( payload = jwt.decode(
token, token,
@ -34,13 +35,13 @@ class JWTCodec:
issuer="discours" issuer="discours"
) )
r = TokenPayload(**payload) r = TokenPayload(**payload)
# print('[auth.jwtcodec] debug payload %r' % r) print('[auth.jwtcodec] debug token %r' % r)
return r return r
except jwt.InvalidIssuedAtError: 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') raise ExpiredToken('check token issued time')
except jwt.ExpiredSignatureError: except jwt.ExpiredSignatureError:
print('[auth.jwtcodec] expired signature %r' % r) print('[auth.jwtcodec] expired signature %r' % payload)
raise ExpiredToken('check token lifetime') raise ExpiredToken('check token lifetime')
except jwt.InvalidTokenError: except jwt.InvalidTokenError:
raise InvalidToken('token is not valid') raise InvalidToken('token is not valid')

View File

@ -28,15 +28,15 @@ class SessionToken:
raise e raise e
@classmethod @classmethod
async def get(cls, uid, token): async def get(cls, payload, token):
return await TokenStorage.get(f"{uid}-{token}") return await TokenStorage.get(f"{payload.user_id}-{payload.username}-{token}")
class TokenStorage: class TokenStorage:
@staticmethod @staticmethod
async def get(token_key): async def get(token_key):
print('[tokenstorage.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) return await redis.execute("GET", token_key)
@staticmethod @staticmethod
@ -44,7 +44,7 @@ class TokenStorage:
life_span = ONETIME_TOKEN_LIFE_SPAN life_span = ONETIME_TOKEN_LIFE_SPAN
exp = datetime.now(tz=timezone.utc) + timedelta(seconds=life_span) exp = datetime.now(tz=timezone.utc) + timedelta(seconds=life_span)
one_time_token = JWTCodec.encode(user, exp) 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 return one_time_token
@staticmethod @staticmethod
@ -52,7 +52,7 @@ class TokenStorage:
life_span = SESSION_TOKEN_LIFE_SPAN life_span = SESSION_TOKEN_LIFE_SPAN
exp = datetime.now(tz=timezone.utc) + timedelta(seconds=life_span) exp = datetime.now(tz=timezone.utc) + timedelta(seconds=life_span)
session_token = JWTCodec.encode(user, exp) 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 return session_token
@staticmethod @staticmethod
@ -64,7 +64,7 @@ class TokenStorage:
except: # noqa except: # noqa
pass pass
else: else:
await redis.execute("DEL", f"{payload.user_id}-{token}") await redis.execute("DEL", f"{payload.user_id}-{payload.username}-{token}")
return True return True
@staticmethod @staticmethod

View File

@ -47,7 +47,7 @@ async def confirm_email(_, info, token):
print('[resolvers.auth] confirm email by token') print('[resolvers.auth] confirm email by token')
payload = JWTCodec.decode(token) payload = JWTCodec.decode(token)
user_id = payload.user_id 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: with local_session() as session:
user = session.query(User).where(User.id == user_id).first() user = session.query(User).where(User.id == user_id).first()
session_token = await TokenStorage.create_session(user) session_token = await TokenStorage.create_session(user)