revoke access_tokens
This commit is contained in:
@@ -4,6 +4,7 @@ from uuid import UUID
|
||||
|
||||
from fastapi import Request
|
||||
|
||||
from src.cache.redis_client import redis_client
|
||||
from src.database.auth.refresh_tokens import JwtCrudActions
|
||||
from src.database.users.crud import UsersCrudActions
|
||||
from src.errors.http_errors.errors import Errors
|
||||
@@ -52,8 +53,13 @@ class CurrentUserService:
|
||||
async def get_current_user(self, token:str, *permissions: str)->UserOut:
|
||||
|
||||
payload= await self.jwt_service.jwt_decode(token)
|
||||
|
||||
sub=payload.get("sub")
|
||||
|
||||
jti_access=payload.get("jti")
|
||||
|
||||
if jti_access and await redis_client.get(f"revoked_access_token:{jti_access}"):
|
||||
raise self.error.credentials_error(detail="Token has been revoked")
|
||||
|
||||
try:
|
||||
sub=UUID(sub)
|
||||
except (ValueError, TypeError) as e:
|
||||
@@ -167,21 +173,34 @@ class CurrentUserService:
|
||||
|
||||
|
||||
|
||||
async def logout(self, refresh_token:str)->bool:
|
||||
async def logout(self, refresh_token:str, access_token:str)->bool:
|
||||
|
||||
'''decode current refresh token'''
|
||||
payload=await self.jwt_service.jwt_decode(refresh_token)
|
||||
payload_refresh=await self.jwt_service.jwt_decode(refresh_token)
|
||||
|
||||
if (jti:=payload.get("jti")) is None:
|
||||
raise self.error.credentials_error(detail="Jwt token is incorrect")
|
||||
'''decode current access token'''
|
||||
payload_access=await self.jwt_service.jwt_decode(access_token)
|
||||
|
||||
|
||||
if (jti_refresh:=payload_refresh.get("jti")) is None:
|
||||
raise self.error.credentials_error(detail="Jwt refresh token is incorrect")
|
||||
|
||||
if (jti_access:=payload_access.get("jti")) is None or (exp_access:=payload_access.get("exp")) is None:
|
||||
raise self.error.credentials_error(detail="Jwt access token is incorrect")
|
||||
|
||||
try:
|
||||
jti=UUID(jti)
|
||||
jti_refresh=UUID(jti_refresh)
|
||||
jti_access=UUID(jti_access)
|
||||
except (ValueError, TypeError, AttributeError) as e:
|
||||
raise self.error.credentials_error(detail="Jwt token is incorrect") from e
|
||||
|
||||
if jti_access and exp_access:
|
||||
exp_datetime = datetime.fromtimestamp(exp_access, tz=UTC)
|
||||
remaining_ttl = max(int((exp_datetime - datetime.now(UTC)).total_seconds()), 1)
|
||||
await redis_client.set(f"revoked_access_token:{jti_access}", "1", ex=remaining_ttl) #revoke tokens and set them to redis until their exp ends
|
||||
|
||||
'''logout by assigning revoked flag'''
|
||||
if await self.jwt_db_actions.logout(jti):
|
||||
if await self.jwt_db_actions.logout(jti_refresh):
|
||||
return True
|
||||
else:
|
||||
raise self.error.not_found_error(detail="Refresh Token Not Found")
|
||||
|
||||
@@ -35,14 +35,17 @@ class JwtService:
|
||||
if not (data.get("sub")) or data.get("sub") == "":
|
||||
raise self.error.credentials_error(detail="Jwt token is incorrect")
|
||||
|
||||
|
||||
async def create_access_token(self, data:dict)->str:
|
||||
|
||||
user_info=data.copy()
|
||||
jti=str(uuid4())
|
||||
|
||||
await self._validate_sub(user_info)
|
||||
|
||||
user_info.update({"exp": datetime.now(UTC)+timedelta(minutes=env_settings.ACCESS_TOKEN_EXPIRE_MINUTES),
|
||||
"token_type":"access"})
|
||||
"token_type":"access",
|
||||
"jti":jti})
|
||||
return jwt.encode(user_info, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user