Access Token 和 Refresh Token 的双令牌机制,维持登陆状态

目录


为了实现客户端在 JWT Token 过期后自动更新 Token,通常会采用 Access Token 和 Refresh Token 的双令牌机制。以下是实现自动更新 Token 的具体方法和流程:

1. 双令牌机制

  • Access Token:有效期较短(例如 15 分钟到 1 小时),用于客户端访问受保护的资源。
  • Refresh Token:有效期较长(例如 7 天到 30 天),用于刷新过期的 Access Token。

2. 工作流程

  1. 用户登录

    • 用户提交用户名和密码给服务器。
    • 服务器验证成功后,生成 Access Token 和 Refresh Token。
    • Access Token 有较短的有效期,而 Refresh Token 有较长的有效期。
  2. Access Token 过期

    • 当 Access Token 过期时,客户端在发送请求时会携带过期的 Access Token 和有效的 Refresh Token。
    • 客户端不需要让用户重新登录,而是使用 Refresh Token 向服务器请求刷新一个新的 Access Token。
    • 服务器验证 Refresh Token,如果有效,则生成新的 Access Token 和新的 Refresh Token(防止 Refresh Token 被盗用),并将它们返回给客户端。
    • 客户端用新的 Access Token 继续访问 API。
  3. Token 刷新失败

    • 如果 Refresh Token 也过期,或者 Refresh Token 被篡改,服务器会要求用户重新登录。

3. 客户端实现

客户端需要在每次请求时检查 Access Token 是否过期,并在过期时自动使用 Refresh Token 请求新的 Access Token。以下是一个示例流程:

客户端请求逻辑

  1. 发送请求
    • 客户端发送请求时,携带 Access Token。
  2. 检查响应
    • 如果服务器返回 401 Unauthorized(表示 Access Token 过期),客户端自动使用 Refresh Token 请求新的 Access Token。
  3. 刷新 Token
    • 客户端向服务器发送一个刷新请求,携带 Refresh Token。
    • 服务器验证 Refresh Token,如果有效,返回新的 Access Token 和新的 Refresh Token。
    • 客户端更新本地存储的 Access Token 和 Refresh Token,并重新发送之前失败的请求。

4. 服务器端实现

服务器端需要提供一个专门的接口用于刷新 Token。以下是一个示例:

python 复制代码
from flask import Flask, request, jsonify
import jwt
import datetime

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key_here'  # 替换为你的密钥

# 模拟用户数据库
users = {
    "user1": "password1",
    "user2": "password2"
}

def create_token(payload, expiry_minutes=60):
    """生成 Access Token"""
    expiry = datetime.datetime.utcnow() + datetime.timedelta(minutes=expiry_minutes)
    return jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')

def create_refresh_token(payload, expiry_days=7):
    """生成 Refresh Token"""
    expiry = datetime.datetime.utcnow() + datetime.timedelta(days=expiry_days)
    return jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')

@app.route('/login', methods=['POST'])
def login():
    # 获取请求中的用户名和密码
    username = request.json.get('username')
    password = request.json.get('password')

    # 验证用户名和密码
    if username not in users or users[username] != password:
        return jsonify({'error': 'Invalid username or password'}), 401

    # 生成 Access Token 和 Refresh Token
    access_token = create_token({"user_id": username})
    refresh_token = create_refresh_token({"user_id": username})

    # 返回 Token
    return jsonify({
        'access_token': access_token,
        'refresh_token': refresh_token
    })

@app.route('/token/refresh', methods=['POST']) # 刷新 Token 的接口
def refresh_token():
    refresh_token = request.json.get('refresh_token')
    if not refresh_token:
        return jsonify({'error': 'Refresh token is missing'}), 400

    try:
        # 解码 Refresh Token
        payload = jwt.decode(refresh_token, app.config['SECRET_KEY'], algorithms=['HS256'])
        user_id = payload['user_id']

        # 生成新的 Access Token 和 Refresh Token
        new_access_token = create_token({"user_id": user_id})
        new_refresh_token = create_refresh_token({"user_id": user_id})

        return jsonify({
            'access_token': new_access_token,
            'refresh_token': new_refresh_token
        })
    except jwt.ExpiredSignatureError:
        return jsonify({'error': 'Refresh token has expired'}), 401
    except jwt.InvalidTokenError:
        return jsonify({'error': 'Invalid refresh token'}), 401

if __name__ == '__main__':
    app.run(debug=True)

5. 注意事项

  • 安全性:确保 Refresh Token 的安全性,避免泄露。可以对 Refresh Token 的使用次数进行限制。
  • 用户体验:通过自动刷新机制,用户无需频繁重新登录,提升用户体验。
  • 存储方式:客户端可以将 Token 存储在本地,存储方式可以考虑SQLite 数据库、文件存储、Android Keystore、EncryptedSharedPreferences、SQLCiphe。
拓展:Token在客户端安全存储的几种方式

Token在客户端安全存储的几种方式

相关推荐
废弃的小码农19 小时前
测试基础--Day01--软件测试基础理论
python·功能测试·测试工具
火白学安全20 小时前
《Python红队攻防脚本零基础编写:入门篇(一)》
python·安全·web安全·网络安全·系统安全
携欢20 小时前
PortSwigger靶场之Exploiting server-side parameter pollution in a REST URL通关秘籍
前端·javascript·安全
梦想的初衷~20 小时前
Python驱动的无人机多光谱-点云融合技术在生态三维建模与碳储量、生物量、LULC估算中的全流程实战
python·无人机·遥感·多光谱
一晌小贪欢20 小时前
Python爬虫第3课:BeautifulSoup解析HTML与数据提取
爬虫·python·网络爬虫·beautifulsoup·python爬虫·python3·requests
好家伙VCC20 小时前
**发散创新:渗透测试方法的深度探索与实践**随着网络安全形势日益严峻,渗透测试作为评估系统安全的
java·python·安全·web安全·系统安全
机器学习之心20 小时前
一个基于无干扰增量容量(IC)和差分电压(DV)分析的锂离子电池健康状态(SOH)与剩余寿命(RUL)预测的Python实现
python
人邮异步社区21 小时前
内网攻防实战图谱:从红队视角构建安全对抗体系
网络·安全·web安全
胡耀超1 天前
大数据平台安全指南——大数据平台安全架构全景:从认证授权到数据治理的企业级实践指南——认证、授权、审计、加密四大支柱
安全·数据治理·数据安全·权限管理·安全架构·hadoop生态·合规审计
深盾科技1 天前
C/C++逆向分析实战:变量的奥秘与安全防护
c语言·c++·安全