fastapi登录认证机制

本文展示了如何在Python的FastAPI框架中实现OAuth2密码模式的JWT(JSONWebToken)认证。代码创建了JWTtoken的加密和解密函数,并定义了一个自定义的HTTPException来处理认证失败的情况。用户登录后,系统会生成JWTtoken,之后的请求可以通过依赖解析验证这个token。
摘要由CSDN通过智能技术生成

1.user_OAuth2.py

from datetime import datetime, timedelta
from jose import JWTError, jwt
from typing import Optional
from fastapi import HTTPException,status

#盐值
SECRET_KEY = "ed970259a19edfedf1010199c7002d183bd15bcaec612481b29bac1cb83d8137"

#加密方式
ALGORITHM = "HS256"

#过期时间
ACCESS_TOKEN_EXPIRE_MINUTES = 10

# 定义一个验证异常的返回
credentials_exception = HTTPException(

    #自定义状态码
    status_code=status.HTTP_401_UNAUTHORIZED,

    #返回信息
    detail="认证失败",

    #响应头
    # 根据OAuth2规范, 认证失败需要在响应头中添加如下键值对
    headers={'WWW-Authenticate': "Bearer"}
)

def create_jwt_token(data: dict, expire_delta: Optional[timedelta] = None):
    '''加密token'''

    # 如果传入了过期时间, 那么就是用该时间, 否则使用默认的时间
    expire = datetime.utcnow() + expire_delta if expire_delta else datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)

    # 需要加密的数据data必须为一个字典类型, 在数据中添加过期时间键值对, 键exp的名称是固定写法
    data.update({'exp': expire})

    # 进行jwt加密
    #data:需要加密的字典类型的数据,key:加密需要使用的秘钥, 也叫做盐值,algorithm:加密的算法, 默认为ALGORITHMS.HS256
    token = jwt.encode(claims=data, key=SECRET_KEY, algorithm=ALGORITHM)

    print(token)
    return token


def decrypt_jwt_token(token):
    '''解密token, 返回被加密的字典'''

    try:
        #解密
        payload = jwt.decode(token=token, key=SECRET_KEY, algorithms=[ALGORITHM])
        print(f'payload: {payload}')

        # 从解密的字典中获取数据
        user_id = payload.get('user_id')
        nick_name = payload.get('nick_name')
        user_name = payload.get('user_name')

        #返回解密内容
        return {'nick_name': nick_name, 'user_name': user_name, 'user_id': user_id}

    except JWTError as e:
        # 返回异常自定义验证
        raise credentials_exception

user.py

from fastapi import FastAPI,Depends
from pydantic import BaseModel
from utils import mysql
from .user_OAuth2 import create_jwt_token,decrypt_jwt_token
from typing import Union
from fastapi.security import OAuth2PasswordBearer

# 实例化oauth2, tokenUrl给一个生成token的接口
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='/login')

#实例化fastapi
app = FastAPI()



class User(BaseModel):
    '''用户类-继承BaseModel模型'''

    username:str
    password:str
    id: Union[str, None] = None
    nickname:Union[str,None]=None



def Select_user(user:User):

    '''
    查询用户是否存在
    :param user:用户类
    :return: 用户信息 json 或 None
    '''

    try:

        #sql
        sql = '''SELECT user_name,password,id,nick_name FROM `user` WHERE user_name=%s AND password=%s'''

        #查询
        data = mysql.Select(sql, (user.username, user.password))

        #赋值
        user.username= data[0][0]
        user.password= data[0][1]
        user.id= data[0][2]
        user.nickname= data[0][3]

        #返回数据
        return user

    except Exception as e:
        print(e)

        #抛出异常返回 none
        return None




@app.post('/login')
def login(user: User=Depends(Select_user)):
    '''
    :param user: 类型为User类,Depends
    :return:
    '''
    if user:
        #加密 ,生成token
        token = create_jwt_token({'user_id':user.id,'nick_name':user.nickname,'user_name':user.username})
        return {'code':200,'access_token':token,'token_type': 'bearer','msg':'登录成功'}
    
    return {'code':100,'msg':'登录失败'}



@app.get('/me')
async def test(token: str = Depends(oauth2_scheme)):
    #解密
    jwt_token = decrypt_jwt_token(token)
    return jwt_token



@app.get('/')
def test(s: str = Depends(oauth2_scheme)):
    print(s)
    return {'hello': s}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值