1111from typing_extensions import Annotated
1212
1313from backend .app .common .exception .errors import AuthorizationError , TokenError
14+ from backend .app .common .redis import redis_client
1415from backend .app .core .conf import settings
1516from backend .app .crud .crud_user import UserDao
1617from backend .app .database .db_mysql import CurrentSession
@@ -42,28 +43,34 @@ def password_verify(plain_password: str, hashed_password: str) -> bool:
4243 return pwd_context .verify (plain_password , hashed_password )
4344
4445
45- def create_access_token (data : int | Any , expires_delta : timedelta | None = None ) -> str :
46+ async def create_access_token (sub : int | Any , data : dict , expires_delta : timedelta | None = None ) -> str :
4647 """
4748 Generate encryption token
4849
50+ :param sub: The subject/userid of the JWT
4951 :param data: Data transferred to the token
5052 :param expires_delta: Increased expiry time
5153 :return:
5254 """
5355 if expires_delta :
5456 expires = datetime .utcnow () + expires_delta
57+ expire_seconds = expires_delta .total_seconds ()
5558 else :
56- expires = datetime .utcnow () + timedelta (settings .TOKEN_EXPIRE_MINUTES )
57- to_encode = {'exp' : expires , 'sub' : str (data [0 ]), 'role_ids' : str (data [1 ])}
58- encoded_jwt = jwt .encode (to_encode , settings .TOKEN_SECRET_KEY , settings .TOKEN_ALGORITHM )
59- return encoded_jwt
60-
61-
62- async def get_current_user (db : CurrentSession , token : str = Depends (oauth2_schema )) -> User :
59+ expires = datetime .utcnow () + timedelta (seconds = settings .TOKEN_EXPIRE_MINUTES )
60+ expire_seconds = settings .TOKEN_EXPIRE_SECONDS
61+ to_encode = {'exp' : expires , 'sub' : str (sub ), ** data }
62+ token = jwt .encode (to_encode , settings .TOKEN_SECRET_KEY , settings .TOKEN_ALGORITHM )
63+ if sub not in settings .TOKEN_WHITE_LIST :
64+ await redis_client .delete (f'token:{ sub } :*' )
65+ key = f'token:{ sub } :{ token } '
66+ await redis_client .setex (key , expire_seconds , token )
67+ return token
68+
69+
70+ async def jwt_authentication (token : str = Depends (oauth2_schema )):
6371 """
64- Get the current user through tokens
72+ JWT authentication
6573
66- :param db:
6774 :param token:
6875 :return:
6976 """
@@ -73,8 +80,25 @@ async def get_current_user(db: CurrentSession, token: str = Depends(oauth2_schem
7380 user_role = payload .get ('role_ids' )
7481 if not user_id or not user_role :
7582 raise TokenError
83+ # 验证token是否有效
84+ key = f'token:{ user_id } :{ token } '
85+ valid_token = await redis_client .get (key )
86+ if not valid_token :
87+ raise TokenError
88+ return {'payload' : payload , 'token' : token }
7689 except (jwt .JWTError , ValidationError ):
7790 raise TokenError
91+
92+
93+ async def get_current_user (db : CurrentSession , data : dict = Depends (jwt_authentication )) -> User :
94+ """
95+ Get the current user through tokens
96+
97+ :param db:
98+ :param data:
99+ :return:
100+ """
101+ user_id = data .get ('payload' ).get ('sub' )
78102 user = await UserDao .get_user_with_relation (db , user_id = user_id )
79103 if not user :
80104 raise TokenError
@@ -97,6 +121,8 @@ async def get_current_is_superuser(user: User = Depends(get_current_user)):
97121# User Annotated
98122CurrentUser = Annotated [User , Depends (get_current_user )]
99123CurrentSuperUser = Annotated [bool , Depends (get_current_is_superuser )]
124+ # Token dependency injection
125+ JwtAuthentication = Annotated [dict , Depends (jwt_authentication )]
100126# Permission dependency injection
101127DependsUser = Depends (get_current_user )
102128DependsSuperUser = Depends (get_current_is_superuser )
0 commit comments