首页 > 其他分享 >如何实现无感刷新 Token

如何实现无感刷新 Token

时间:2024-07-30 19:09:17浏览次数:10  
标签:令牌 error token refresh access Token 刷新 无感

使用 JSON Web Token (JWT) 进行身份验证是一种常见的做法。然而,JWT 通常有一个有效期,当用户的令牌过期时,如果不进行处理,用户将被迫重新登录,这会影响用户体验。为了解决这个问题,可以实现无感刷新(silent refresh)机制,自动刷新令牌而不打扰用户。

本文将介绍如何实现无感刷新 Token 的技术方案,包括以下步骤:

  1. 生成和使用访问令牌和刷新令牌
  2. 自动刷新访问令牌
  3. 处理令牌刷新失败的情况

1. 生成和使用访问令牌和刷新令牌

生成访问令牌和刷新令牌

在用户登录时,服务器生成两个令牌:访问令牌(access token)和刷新令牌(refresh token)。访问令牌用于验证用户身份,有较短的有效期;刷新令牌用于获取新的访问令牌,有较长的有效期。

import jwt
import datetime

def generate_tokens(user_id):
    access_token = jwt.encode({
        'user_id': user_id,
        'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
    }, 'access_secret_key', algorithm='HS256')

    refresh_token = jwt.encode({
        'user_id': user_id,
        'exp': datetime.datetime.utcnow() + datetime.timedelta(days=7)
    }, 'refresh_secret_key', algorithm='HS256')

    return access_token, refresh_token

 

返回令牌给客户端

在用户登录成功后,将访问令牌和刷新令牌返回给客户端,并将它们存储在安全的位置。

// 示例:使用 axios 处理登录请求并存储令牌
axios.post('https://yourapi.com/login', {
  username: 'user',
  password: 'password'
}).then(response => {
  localStorage.setItem('access_token', response.data.access_token);
  localStorage.setItem('refresh_token', response.data.refresh_token);
});

 

2. 自动刷新访问令牌

拦截请求并检查令牌

在前端,使用 Axios 拦截器检查每个请求的访问令牌是否即将过期。如果即将过期,使用刷新令牌获取新的访问令牌。

import axios from 'axios';
import jwt_decode from 'jwt-decode';

// 创建 Axios 实例
const api = axios.create({
  baseURL: 'https://yourapi.com',
});

// 添加请求拦截器
api.interceptors.request.use(async (config) => {
  let accessToken = localStorage.getItem('access_token');
  const refreshToken = localStorage.getItem('refresh_token');

  if (accessToken) {
    const { exp } = jwt_decode(accessToken);
    const expirationTime = exp * 1000;
    const currentTime = Date.now();

    // 如果访问令牌即将过期,刷新令牌
    if (expirationTime - currentTime < 5 * 60 * 1000) { // 5 分钟
      try {
        const response = await axios.post('https://yourapi.com/refresh-token', { token: refreshToken });
        accessToken = response.data.access_token;
        localStorage.setItem('access_token', accessToken);
      } catch (error) {
        console.error('Unable to refresh token', error);
        // 刷新令牌失败,处理失败逻辑
      }
    }

    config.headers['Authorization'] = `Bearer ${accessToken}`;
  }

  return config;
}, error => {
  return Promise.reject(error);
});

 

服务器端刷新令牌

在服务器端,实现刷新令牌的逻辑,验证刷新令牌并生成新的访问令牌。

from flask import Flask, request, jsonify
import jwt
import datetime

app = Flask(__name__)

@app.route('/refresh-token', methods=['POST'])
def refresh_token():
    try:
        refresh_token = request.json.get('token')
        decoded_refresh_token = jwt.decode(refresh_token, 'refresh_secret_key', algorithms=['HS256'])
        user_id = decoded_refresh_token['user_id']

        new_access_token = jwt.encode({
            'user_id': user_id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
        }, 'access_secret_key', algorithm='HS256')

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

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

 

3. 处理令牌刷新失败的情况

在实际应用中,可能会遇到刷新令牌失败的情况,如刷新令牌已过期或无效。此时需要处理这些情况,通常是引导用户重新登录。

在前端处理刷新失败

在前端拦截响应错误,当刷新令牌失败时,清除存储的令牌并重定向用户到登录页面。

// 添加响应拦截器
api.interceptors.response.use(response => {
  return response;
}, error => {
  if (error.response.status === 401 && error.config && !error.config.__isRetryRequest) {
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');
    window.location.href = '/login';
  }
  return Promise.reject(error);
});

 

总结

无感刷新(silent refresh)机制通过在后台自动刷新访问令牌,确保用户在使用应用时不会因令牌过期而被迫重新登录,从而提高用户体验。实现无感刷新需要前后端协同工作,前端负责检测和刷新令牌,后端提供刷新令牌的接口。通过合理的设计和实现,可以有效地提高应用的安全性和用户体验。

标签:令牌,error,token,refresh,access,Token,刷新,无感
From: https://www.cnblogs.com/zx618/p/18333176

相关文章

  • 辅助分析研判,刷新代码安全打开方式(上)
    数字化时代,代码已成为企业发展的重要基石。随着技术的日新月异,安全从业者的日常工作中常见形形色色的应用场景,高效的AI编程代码助手能帮助程序员更游刃有余地进行代码、数据等内容的分析和辅助研判。文心快码BaiduComate具备代码解释、代码审计,以及自动检测漏洞并修复等多样......
  • 安卓下拉刷新SmartRefreshLayout组件的使用
    在此本人使用的是来源于gitee仓库上的组件SmartRefreshLayout:下拉刷新、上拉加载、RefreshLayout、OverScroll,Android智能下拉刷新框架,支持越界回弹,具有极强的扩展性,集成了几十种炫酷的Header和Footer。上面有各种样式可以选择,大家可以去gitee上自行搜索拉取仓库使用此组件......
  • 帝国CMS网站定时刷新任务用于定时生成指定页面的功能
    一、定时刷新任务介绍:用于定时生成指定页面的功能。 二、增加定时刷新任务1、登录后台,单击“系统”菜单,选择“管理刷新任务”子菜单,进入管理刷新任务界面:2、进入管理刷新任务界面,点击“增加刷新任务”按钮进入增加刷新任务界面:3、进入增加刷新任务......
  • Pentester Academy -Windows API Exploitation Recipes: Processes, Tokens and Memor
    早年为PentesterAcademy(https://www.pentesteracademy.com/),如今为INE(https://ine.com/)002安装VS社区版https://visualstudio.microsoft.com/zh-hans/003processlistingapi正在运行的是什么:服务,AV,HIDS/IPS等其他attack开始的点:进程注入,内存dump/修改,TokenSt......
  • 【阿里云】通过OpenAPI获取Token(C#)
    使用C#实现https://help.aliyun.com/zh/isi/getting-started/use-http-or-https-to-obtain-an-access-tokenpublicstaticclassTokenHelper{publicstaticasyncTask<string>GetAccessTokenAsync(stringaccessKeyId,stringaccessKeySecret){......
  • GreatSQL 的刷新锁
    GreatSQL的刷新锁前言因为运维小伙伴执行dump备份命令,导致数据库卡住,很多会话都在waitingfortableflush,基于这一故障,我对GreatSQL的刷新锁进行了研究。感兴趣的小伙伴请随我一探究竟吧。刷新锁的症状刷新锁问题的主要症状是数据库会进入嘎然而止的状态,所有需要使用部分或......
  • 基于 token 的登陆系统的实现
    这是一段防爬代码块,我不介意文章被爬取,但请注明出处console.log("作者主页:https://www.cnblogs.com/w-blogg");console.log("原文地址:https://www.cnblogs.com/w-blogg/p/18328093");最近公司搞新项目,有个需求登陆,简单记录一下:app端实现一个登陆系统,七天内如果操作过,则不需......
  • 万亿token!史上最大多模态数据集诞生
    开源多模态大模型或将开始腾飞。点击访问我的技术博客https://ai.weoknow.comhttps://ai.weoknow.com值此Llama3.1占领各大头条之际,又突然冒出了另一个也非常重要的发布——一个规模空前的开源多模态数据集。对大模型来说,数据集的重要性无需多言,甚至可以说没有......
  • 震惊,刷新我的认知,医疗信息数据库sqlserver中计算年龄的sql函数写了200行...
    创作不易只因热爱!!热衷分享,一起成长!“你的鼓励就是我努力付出的动力”sqlserver中年龄计算,HIS系统中年龄计算函数呈现的结果要求:1周岁内显示"几月几天",1周岁以上显示"几岁"CREATEFUNCTIONdbo.FUN_GETBRNL( @birthvarchar(24),--生日 @now......
  • 业务场景---Token无感刷新
    业务场景描述假设用户正在填写一个复杂的表单,由于表单内容繁多,用户花费了很长时间才填完。这时,如果Token已经过期,系统会让用户重新登录,这种体验显然是非常糟糕的。为了避免这种情况,我们需要在Token即将过期或已经过期时,自动刷新Token,而不影响用户正在进行的操作。技术实现思路......