1616from backend .app .crud .crud_user import UserDao
1717from backend .app .database .db_mysql import CurrentSession
1818from backend .app .models import User
19- from backend .app .schemas .token import RefreshTokenTime
2019
2120pwd_context = CryptContext (schemes = ['bcrypt' ], deprecated = 'auto' )
2221
@@ -53,46 +52,60 @@ async def create_access_token(sub: str, expires_delta: timedelta | None = None,
5352 :return:
5453 """
5554 if expires_delta :
56- expire = datetime .utcnow () + expires_delta
55+ expire = datetime .now () + expires_delta
5756 expire_seconds = int (expires_delta .total_seconds ())
5857 else :
59- expire = datetime .utcnow () + timedelta (seconds = settings .TOKEN_EXPIRE_SECONDS )
58+ expire = datetime .now () + timedelta (seconds = settings .TOKEN_EXPIRE_SECONDS )
6059 expire_seconds = settings .TOKEN_EXPIRE_SECONDS
60+ multi_login = kwargs .pop ('multi_login' , None )
6161 to_encode = {'exp' : expire , 'sub' : sub , ** kwargs }
6262 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_prefix (f'{ settings .TOKEN_REDIS_PREFIX } :{ sub } :' )
63+ if multi_login is False :
64+ prefix = f'{ settings .TOKEN_REDIS_PREFIX } :{ sub } :'
65+ await redis_client .delete_prefix (prefix )
6566 key = f'{ settings .TOKEN_REDIS_PREFIX } :{ sub } :{ token } '
6667 await redis_client .setex (key , expire_seconds , token )
6768 return token , expire
6869
6970
70- async def create_refresh_token (
71- sub : str , expire_time : datetime | None = None , custom_expire_time : RefreshTokenTime | None = None , ** kwargs
72- ) -> tuple [str , datetime ]:
71+ async def create_refresh_token (sub : str , expire_time : datetime | None = None , ** kwargs ) -> tuple [str , datetime ]:
7372 """
74- Generate encryption refresh token
73+ Generate encryption refresh token, only used to create a new token
7574
7675 :param sub: The subject/userid of the JWT
7776 :param expire_time: expiry time
78- :param custom_expire_time: custom expiry time
7977 :return:
8078 """
8179 if expire_time :
82- expire = expire_time + timedelta (seconds = settings .TOKEN_EXPIRE_SECONDS )
83- expire_seconds = int ((expire - datetime .utcnow ()).total_seconds ())
84- elif custom_expire_time :
85- expire = custom_expire_time .expire_time
86- expire_seconds = int ((expire - datetime .utcnow ()).total_seconds ())
80+ expire = expire_time + timedelta (seconds = settings .TOKEN_REFRESH_EXPIRE_SECONDS )
81+ expire_seconds = int ((expire - datetime .now ()).total_seconds ())
8782 else :
88- expire = datetime .utcnow () + timedelta (seconds = settings .TOKEN_EXPIRE_SECONDS )
89- expire_seconds = settings .TOKEN_EXPIRE_SECONDS
83+ expire = datetime .now () + timedelta (seconds = settings .TOKEN_REFRESH_EXPIRE_SECONDS )
84+ expire_seconds = settings .TOKEN_REFRESH_EXPIRE_SECONDS
85+ multi_login = kwargs .pop ('multi_login' , None )
9086 to_encode = {'exp' : expire , 'sub' : sub , ** kwargs }
91- token = jwt .encode (to_encode , settings .TOKEN_SECRET_KEY , settings .TOKEN_ALGORITHM )
92- # 刷新 token 时,保持旧 token 有效,不执行删除操作
93- key = f'{ settings .TOKEN_REDIS_PREFIX } :{ sub } :{ token } '
94- await redis_client .setex (key , expire_seconds , token )
95- return token , expire
87+ refresh_token = jwt .encode (to_encode , settings .TOKEN_SECRET_KEY , settings .TOKEN_ALGORITHM )
88+ if multi_login is False :
89+ prefix = f'{ settings .TOKEN_REFRESH_REDIS_PREFIX } :{ sub } :'
90+ await redis_client .delete_prefix (prefix )
91+ key = f'{ settings .TOKEN_REFRESH_REDIS_PREFIX } :{ sub } :{ refresh_token } '
92+ await redis_client .setex (key , expire_seconds , refresh_token )
93+ return refresh_token , expire
94+
95+
96+ async def create_new_token (sub : str , refresh_token : str , ** kwargs ) -> tuple [str , datetime ]:
97+ """
98+ Generate new token
99+
100+ :param sub:
101+ :param refresh_token:
102+ :return:
103+ """
104+ redis_refresh_token = await redis_client .get (f'{ settings .TOKEN_REFRESH_REDIS_PREFIX } :{ sub } :{ refresh_token } ' )
105+ if not redis_refresh_token or redis_refresh_token != refresh_token :
106+ raise TokenError (msg = 'refresh_token 已过期' )
107+ new_token , expire = await create_access_token (sub , ** kwargs )
108+ return new_token , expire
96109
97110
98111def get_token (request : Request ) -> str :
@@ -102,10 +115,10 @@ def get_token(request: Request) -> str:
102115 :return:
103116 """
104117 authorization = request .headers .get ('Authorization' )
105- scheme , param = get_authorization_scheme_param (authorization )
118+ scheme , token = get_authorization_scheme_param (authorization )
106119 if not authorization or scheme .lower () != 'bearer' :
107120 raise TokenError
108- return param
121+ return token
109122
110123
111124def jwt_decode (token : str ) -> tuple [int , list [int ]]:
@@ -118,12 +131,12 @@ def jwt_decode(token: str) -> tuple[int, list[int]]:
118131 try :
119132 payload = jwt .decode (token , settings .TOKEN_SECRET_KEY , algorithms = [settings .TOKEN_ALGORITHM ])
120133 user_id = int (payload .get ('sub' ))
121- user_roles = list (payload .get ('role_ids' ))
122- if not user_id or not user_roles :
134+ role_ids = list (payload .get ('role_ids' ))
135+ if not user_id or not role_ids :
123136 raise TokenError
124137 except (jwt .JWTError , ValidationError , Exception ):
125138 raise TokenError
126- return user_id , user_roles
139+ return user_id , role_ids
127140
128141
129142async def jwt_authentication (token : str = Depends (oauth2_schema )) -> dict [str , int ]:
@@ -137,7 +150,7 @@ async def jwt_authentication(token: str = Depends(oauth2_schema)) -> dict[str, i
137150 key = f'{ settings .TOKEN_REDIS_PREFIX } :{ user_id } :{ token } '
138151 token_verify = await redis_client .get (key )
139152 if not token_verify :
140- raise TokenError
153+ raise TokenError ( msg = 'token 已过期' )
141154 return {'sub' : user_id }
142155
143156
0 commit comments