上篇文章开发了两个接口,但是针对注册的接口密码没有加密,针对登录接口的返回token
没有加密和失效时间等等…
那么本篇主要叙述,针对这个两个接口的处理,首先是基于python-jose
库来生成token
,再基于passlib
库来做密码加密和解密处理。
记得要先安装依赖库:
pip install passlib
pip install python-jose
…..好了,话不多说,下面开始进入正文…..
sc_app/dependencies.py
# -*- coding: utf-8 -*-
# @Time : 2022/4/12 20:20
# @Author : Lifeng
# @File : dependencies.py
# @Software: PyCharm
from typing import Optional
from jose import JWTError, jwt
from sc_app.redispy import redispy
from sc_app import settings as sp
from datetime import timedelta, datetime
from passlib.context import CryptContext
from fastapi import status, Header, HTTPException
def verify_x_token(x_token: str = Header(default="debugfeng")):
"""
校验鉴权
:param x_token:
:return:
"""
if x_token != "debugfeng":
raise HTTPException(status_code=400, detail="not x_token in header !")
def generate_access_token(data: dict, expiration: Optional[timedelta] = None):
"""
生成token并加密
:param data:
:param expiration:
:return:
"""
to_encode = data.copy()
if expiration:
expire = datetime.utcnow() + expiration
else:
expire = datetime.utcnow() + timedelta(days=3)
to_encode.update({"exp": expire})
to_encode_jwt = jwt.encode(to_encode, key=sp.KEY, algorithm=sp.ALGORITHM)
return to_encode_jwt
def verify_token(x_token: str = Header(...), token: str = Header(...)):
"""
获取用户并解密token
:param x_token:
:param token:
:return:
"""
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail={"Message": " 凭证错误或已失效啦...... "},
)
credentials_exception_token = HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail={"Message": " 用户未登录或者登陆 token 已经失效!"}
)
try:
# 解析token值
payload = jwt.decode(token, key=sp.KEY, algorithms=sp.ALGORITHM)
username: str = payload["username"]
# 判断用户是不是空值
if username is None:
raise credentials_exception
# redis读取token值
redis_token = redispy.get_value(username, is_data=True)
# 如不满足条件则抛出错误
if not username and not redis_token and x_token != "debugfeng" and redis_token != token:
raise credentials_e