当前位置: 首页 > article >正文

Vue3+FastAPI中Token的刷新机制(含代码示例)

在Vue3和FastAPI的应用中,token刷新机制通常涉及以下几个步骤:

  1. 登录过程:用户登录时,后端FastAPI验证用户信息,验证通过后生成一个访问令牌(access token)和一个刷新令牌(refresh token)。访问令牌通常有一个较短的过期时间,而刷新令牌则有一个较长的过期时间。
  2. 访问资源:前端Vue3在每次请求后端资源时,需要在请求头中携带访问令牌。
  3. 令牌过期:当访问令牌过期时,后端FastAPI返回一个提示令牌过期的响应。
  4. 刷新令牌:前端Vue3收到令牌过期的响应后,使用刷新令牌向后端发送请求,请求新的访问令牌。
  5. 返回新令牌:后端FastAPI验证刷新令牌,如果有效,则生成新的访问令牌返回给前端。
  6. 使用新令牌:前端Vue3收到新的访问令牌后,使用该令牌继续访问资源。
    下面是一个简化的示例代码:

后端FastAPI

from fastapi import FastAPI, HTTPException, Depends
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel
import jwt
import datetime

app = FastAPI()

# 伪代码:用户数据库和验证逻辑
users_db = {"user1": {"password": "pass1"}}

# 伪代码:密钥和算法
SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"

# 伪代码:访问令牌和刷新令牌的有效期
ACCESS_TOKEN_EXPIRE_MINUTES = 15
REFRESH_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7

class Token(BaseModel):
    access_token: str
    refresh_token: str

def authenticate_user(username: str, password: str):
    user = users_db.get(username)
    if not user or user["password"] != password:
        return False
    return user

def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.datetime.utcnow() + datetime.timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

def create_refresh_token(data: dict):
    to_encode = data.copy()
    expire = datetime.datetime.utcnow() + datetime.timedelta(minutes=REFRESH_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

@app.post("/token", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
    user = authenticate_user(form_data.username, form_data.password)
    if not user:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    access_token = create_access_token(data={"sub": form_data.username})
    refresh_token = create_refresh_token(data={"sub": form_data.username})
    return {"access_token": access_token, "refresh_token": refresh_token}

@app.get("/refresh_token")
async def refresh_token(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username = payload.get("sub")
        if username is None:
            raise HTTPException(status_code=401, detail="Invalid token")
        new_access_token = create_access_token(data={"sub": username})
        return {"access_token": new_access_token}
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token expired")
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Invalid token")

前端Vue3

// 伪代码:Vue3请求刷新令牌
function refreshToken() {
  const refreshToken = localStorage.getItem('refresh_token');
  if (!refreshToken) {
    // 处理没有刷新令牌的情况
    return;
  }
  axios.post('/refresh_token', { refresh_token: refreshToken })
    .then(response => {
      localStorage.setItem('access_token', response.data.access_token);
    })
    .catch(error => {
      // 处理刷新令牌失败的情况
    });
}

// 伪代码:Vue3请求拦截器
axios.interceptors.request.use(config => {
  const accessToken = localStorage.getItem('access_token');
  if (accessToken) {
    config.headers['Authorization'] = `Bearer ${accessToken}`;
  }
  return config;
}, error => {
  return Promise.reject(error);
});

// 伪代码:Vue3响应拦截器
axios.interceptors.response.use(response => {
  return response;
}, error => {
  const originalRequest = error.config;


http://www.kler.cn/a/325787.html

相关文章:

  • Altenergy电力系统 status_zigbee SQL注入漏洞复现(CVE-2024-11305)
  • Figma中文网:UI设计师的新资源宝库
  • 【Redis】使用redis实现登录校验功能
  • 4A架构之间的关系和集成
  • OCRSpace申请free api流程
  • java版询价采购系统 招投标询价竞标投标系统 招投标公告系统源码
  • 鸿蒙HarmonyOS之选择相册文件(照片/视频)方法
  • MySQL之分库分表后带来的“副作用”你是怎么解决的?
  • Servlet 3.0新特征
  • 新能源汽车储充机器人:能源高效与智能调度
  • 【2024.9.29练习】R 格式
  • P9241 [蓝桥杯 2023 省 B] 飞机降落
  • 【MySQL】查询原理 —— B+树查询数据全过程
  • docker安装Portainer CE
  • 华为eNSP:端口隔离
  • 【AI大模型】Prompt Engineering
  • tr命令:替换文本中的字符
  • PHP array+array与array_merge()的区别
  • Vue.js与Flask/Django后端的协同开发研究
  • 2-3树(2-3 Tree):原理、常见算法及其应用
  • JAVA开源项目 新闻推荐系统 计算机毕业设计
  • Flink 本地 idea 调试开启 WebUI
  • 【高分系列卫星简介——高分五号卫星(GF-5)】
  • 【Go语言基础——一个Go语言项目典型的文件结构示例】
  • 扩散模型DDPM代码实践
  • 黑马头条day7-app端文章搜索