首页 > 其他分享 >登录认证装饰器

登录认证装饰器

时间:2023-10-08 10:49:00浏览次数:31  
标签:username 登录 认证 access token user str password 装饰

在 FastAPI 中,你可以使用装饰器来实现登录认证。以下是一个示例,演示如何创建一个自定义的登录认证装饰器,以确保只有授权的用户可以访问某些接口:

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel
from passlib.context import CryptContext
from datetime import datetime, timedelta
from jose import JWTError, jwt
from typing import Optional

app = FastAPI()

# 用户数据库(模拟)
fake_users_db = {
    "user1": {
        "username": "user1",
        "password_hash": "$2b$12$H2xj5hqWiRT.I1bXVevv4uZI1IopTAvw63i3kg0utS6B3id5hMkCG",  # 密码是 "password123"
    }
}

# 密码哈希工具
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# 令牌配置
SECRET_KEY = "your_secret_key"  # 需要替换为安全的密钥
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

# OAuth2密码验证工具
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# 用户模型
class User(BaseModel):
    username: str

# 用户认证令牌模型
class Token(BaseModel):
    access_token: str
    token_type: str

# 用户登录表单
class UserInDB(BaseModel):
    username: str
    password_hash: str

# 用户登录请求模型
class UserLoginRequest(BaseModel):
    username: str
    password: str

# 生成访问令牌
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

# 验证密码
def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

# 获取用户信息
def get_user(username: str):
    if username in fake_users_db:
        user_dict = fake_users_db[username]
        return User(**user_dict)

# 获取用户信息(用于令牌验证)
def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    user = get_user(username)
    if user is None:
        raise credentials_exception
    return user

# 登录认证装饰器
def authenticate_user(username: str, password: str):
    user = get_user(username)
    if user is None or not verify_password(password, user.password_hash):
        return False
    return True

# 登录接口
@app.post("/login", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
    username = form_data.username
    password = form_data.password
    if not authenticate_user(username, password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

# 受保护的资源,需要登录认证
@app.get("/protected-resource", response_model=User)
async def protected_resource(current_user: User = Depends(get_current_user)):
    return current_user

在上述代码中,我们创建了一个自定义的登录认证装饰器 authenticate_user,它接受用户名和密码作为参数,并验证用户的凭据。如果用户验证成功,则返回 True,否则返回 False。接着,我们在登录接口 login_for_access_token 中使用这个装饰器来验证用户的凭据。如果用户凭据验证成功,我们生成了访问令牌,并将其返回给客户端。

受保护的资源接口 protected_resource 使用 Depends(get_current_user) 来进行登录认证,只有在用户成功登录后才能访问。这个接口返回当前登录用户的信息。

请注意,在实际应用中,你需要将用户的密码存储为安全的哈希值,而不是明文密码。示例中使用了密码哈希工具 passlib 来进行密码哈希和验证。此外,你还需要替换示例中的 SECRET_KEY 为一个真实的安全密钥,以确保令牌的安全性。

上述代码提供了一个简单的用户认证和令牌生成的示例,你可以根据自己的应用需求进行修改和扩展。

标签:username,登录,认证,access,token,user,str,password,装饰
From: https://www.cnblogs.com/yuezongke/p/17748299.html

相关文章

  • destoon : 后台无法登录问题解决
    经常有朋友在destoon搬家的时候,数据还原之后,会出现后台无法登录的情况.具体表现为后台帐号密码输入后点击确定,页面刷新.并没有跳转到相应后台页面.但是如果帐号密码输入错误,会提示密码错误的情况.这种情况多半是原系统设置中,设置了cookie作用域的问题,如......
  • 谷歌记住密码,设置浏览器 免登录
      """"读chrome本地cookie数据(需要先手动登录勾选记住密码),实现免登陆操作注意:关闭chrome浏览器,否则运行报错!!!"""fromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsdefget_cookie(url):#实例......
  • 【实用】登录图形认证 图形码 验证码 中文图形验证码 动态图形验证码 图片验证码 验证
    后端测试: 主要code:https://www.cnblogs.com/liuguiqing/p/17722366.html ......
  • pig4cloud框架系列五:OAuth2之授权码模式认证
    前言:OAuth2目前被广泛用于第三方登录场景中,用于鉴权,认证。本文主要简单介绍一下授权码模式认证。场景:使用微信登录迅雷一,名词概念1,第三方应用程序:迅雷2,服务提供商:微信3,资源所有者:登录用户4,认证服务器:微信用来处理认证的服务器5,资源服务器:微信存放用户生成的资源的服务器,它......
  • python的装饰器
    python的装饰器1、装饰器的定义给已有的函数添加额外功能的函数,它本质上就是一个闭包函数。装饰器的功能特点:不修改已有函数的功能特点不修改已有函数的调用方式给已有函数添加额外的功能需求:给comment函数添加一个额外功能(需要先登陆,再评论)要求:不能改变现有comment函数......
  • Django实战项目-学习任务系统-用户登录
    第一步:先创建一个Django应用程序框架代码1,先创建一个Django项目django-adminstartprojectmysite将创建一个目录,其布局如下:mysite/manage.pymysite/__init__.pysettings.pyurls.pyasgi.pywsgi.py2,再创建一个Dja......
  • 最高评级!华为云CodeArts Board获信通院软件研发效能度量平台先进级认证
    9月26日,华为云CodeArtsBoard获得了中国信通院《云上软件研发效能度量分级模型》的先进级最高级评估,达到了软件研发效能度量平台评估的通用效能度量能力、组织效能模型、项目效能模型、资源效能模型、个人效能模型、研发效能评价模型、项目管理域、开发域、测试域、运维/运营域的先......
  • 登录删除帖子
    优化后的代码#导包fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromtimeimportsleepfromselenium.webdriver.chrome.optionsimportOptionsimportddddocr#定义类classGetEle:def__init__(self,driver):self.dr......
  • 解除Windows11 最新iso镜像新限制(微软账户登录和需要TPM)一法
        Windows11新镜像ISO文件安装时逼着你非得绑定微软账户,想继续像Windows7那样用本地账户登录。现在不管是Windows11的21H2还是22H2,装系统都得硬着头皮登录微软账户,哪怕你断了网也别想装。以下方法可以避免这个限制,同时解决不需要TPM的问题。:使用Rufus制作USB安装盘,Ru......
  • 华为认证 | HCIE考试流程具体包含哪些?
    HCIE(华为认证网络工程师)是一项认可的网络专业认证,旨在评估个人在网络领域的高级知识和技能。获得HCIE认证需要通过一系列考试,因此在本文中,我们将详细介绍HCIE认证的考试流程,以帮助有兴趣追求该认证的人更好地了解相关内容。01HCIE认证概述首先,让我们简单了解一下HCIE认证的背景。H......