问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

无感刷新机制:智能系统的新宠儿?

创作时间:
作者:
@小白创作中心

无感刷新机制:智能系统的新宠儿?

引用
CSDN
9
来源
1.
https://blog.csdn.net/qq_36208612/article/details/139545599
2.
https://blog.csdn.net/m0_58600248/article/details/138916457
3.
https://m.blog.csdn.net/2401_89323925/article/details/145165700
4.
https://cloud.baidu.com/article/3211839
5.
https://blog.csdn.net/u012723183/article/details/136700195
6.
https://zhidao.baidu.com/question/1958727165501063588.html
7.
https://zhidao.baidu.com/question/2000771775062192627.html
8.
https://juejin.cn/post/7356240651040489487
9.
https://www.showapi.com/news/article/677dea394ddd79f11a1bcef4

在现代Web应用中,使用Token进行身份验证是一种常见方法。然而,当Token过期时,用户需要重新登录才能继续访问受保护资源,这会打断用户体验。引入了无感刷新机制后,即使Token即将过期,也能自动刷新,使用户在无感知的情况下继续操作。这种机制不仅提升了用户体验,还保证了系统的安全性。具体实现需根据项目需求和技术栈进行调整。

01

无感刷新机制的技术原理

无感刷新机制的核心是在Token过期前自动获取新的Token,确保用户会话的连续性。其基本流程如下:

  1. 检测过期:在请求发送前或响应返回时检查Token的有效期。
  2. 刷新逻辑
    • 使用Refresh Token获取新的Access Token(前端场景)。
    • 通过过滤器自动刷新JWT Token(后端场景,如Spring Boot)。

这种机制的关键在于:

  • 双Token机制:使用短有效期的Access Token和长有效期的Refresh Token。
  • 自动刷新:在Token过期前自动发起刷新请求。
  • 透明处理:刷新过程对用户完全透明,不影响正常使用。
02

前端实现示例

在前端应用中,通常使用Axios拦截器来实现无感刷新。以下是一个基于Vue.js的示例:

import axios from 'axios';
import store from './store';

axios.interceptors.request.use(config => {
  const token = store.state.token;
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
}, error => {
  return Promise.reject(error);
});

axios.interceptors.response.use(response => {
  return response;
}, async function (error) {
  if (error.response.status === 401) {
    try {
      const refreshToken = store.state.refreshToken;
      const res = await axios.post('/refresh_token', { refreshToken });
      store.commit('setToken', res.data.accessToken);
      store.commit('setRefreshToken', res.data.refreshToken);
      return axios(error.config);
    } catch (refreshError) {
      store.commit('logout');
      router.push('/login');
    }
  }
  return Promise.reject(error);
});

在这个示例中:

  1. 请求拦截器负责在请求头中添加Token。
  2. 响应拦截器捕获401错误(Token过期),触发刷新逻辑。
  3. 使用Refresh Token获取新Token,并更新存储中的Token。
  4. 刷新成功后重新发送原始请求。
03

后端实现示例

在后端,以Spring Boot为例,可以通过JWT工具类和过滤器实现无感刷新:

public class JwtTokenUtil {
  public String generateToken(UserDetails userDetails) {
    Map<String, Object> claims = new HashMap<>();
    return Jwts.builder()
        .setClaims(claims)
        .setSubject(userDetails.getUsername())
        .setIssuedAt(new Date())
        .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
        .signWith(SignatureAlgorithm.HS512, secret)
        .compact();
  }

  public boolean validateToken(String token, UserDetails userDetails) {
    final String username = getUsernameFromToken(token);
    return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
  }

  private boolean isTokenExpired(String token) {
    final Date expiration = getExpirationDateFromToken(token);
    return expiration.before(new Date());
  }
}
public class JwtRequestFilter extends OncePerRequestFilter {
  @Autowired
  private JwtUserDetailsService userDetailsService;

  @Autowired
  private JwtTokenUtil jwtTokenUtil;

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
      throws ServletException, IOException {
    final String requestTokenHeader = request.getHeader("Authorization");

    String username = null;
    String jwtToken = null;
    if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
      jwtToken = requestTokenHeader.substring(7);
      try {
        username = jwtTokenUtil.getUsernameFromToken(jwtToken);
      } catch (IllegalArgumentException e) {
        logger.warn("Unable to get JWT Token");
      } catch (ExpiredJwtException e) {
        logger.warn("JWT Token has expired");
      }
    }

    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
      UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

      if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
            userDetails, null, userDetails.getAuthorities());
        usernamePasswordAuthenticationToken
            .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
      }
    }
    chain.doFilter(request, response);
  }
}

在这个示例中:

  1. JwtTokenUtil负责生成和验证JWT Token。
  2. JwtRequestFilter在请求到达控制器前检查Token,必要时自动刷新并放行。
04

微信小程序实现

在微信小程序中,无感刷新机制的实现与前端Web应用类似,但需要特别注意本地存储的安全性:

  1. 本地存储:保存Token和过期时间。
  2. 启动时验证:在onLaunchonShow中检查Token有效性,提前刷新即将过期的Token。
  3. 登录与刷新:提供刷新Token接口,失败时重新登录。
// app.js
App({
  onLaunch: function () {
    const token = wx.getStorageSync('token');
    const refreshToken = wx.getStorageSync('refreshToken');
    const tokenExpireTime = wx.getStorageSync('tokenExpireTime');

    if (token && refreshToken && tokenExpireTime > Date.now()) {
      this.checkTokenValidity();
    }
  },

  checkTokenValidity: function () {
    wx.request({
      url: 'https://your-api.com/check_token',
      method: 'GET',
      header: {
        'Authorization': 'Bearer ' + wx.getStorageSync('token')
      },
      success: (res) => {
        if (res.data.code === 401) {
          this.refreshToken();
        }
      }
    });
  },

  refreshToken: function () {
    wx.request({
      url: 'https://your-api.com/refresh_token',
      method: 'POST',
      data: {
        refreshToken: wx.getStorageSync('refreshToken')
      },
      success: (res) => {
        if (res.data.code === 200) {
          wx.setStorageSync('token', res.data.token);
          wx.setStorageSync('tokenExpireTime', Date.now() + res.data.expiresIn * 1000);
        } else {
          wx.removeStorageSync('token');
          wx.removeStorageSync('refreshToken');
          wx.navigateTo({
            url: '/pages/login/login'
          });
        }
      }
    });
  }
});
05

最佳实践

  1. 双Token机制:Access Token设置较短有效期(如15分钟),Refresh Token设置较长有效期(如1小时)。
  2. 前端实现要点
    • 使用拦截器处理Token刷新逻辑。
    • 设置标志位防止重复刷新。
    • 缓存待执行的请求,在Token刷新成功后重新发送。
  3. 后端实现要点
    • 提供安全的Token刷新接口。
    • 使用过滤器检查Token有效性。
    • 确保Refresh Token的安全存储和传输。
  4. 错误处理:如果Token刷新失败,应引导用户重新登录,并提供友好的提示信息。
  5. 安全性考虑
    • Refresh Token也需要定期更新,避免长期暴露。
    • 注意防止XSS和CSRF攻击。
    • 使用HTTPS确保数据传输安全。
06

未来趋势

随着技术的发展,无感刷新机制可能会有以下改进方向:

  1. 智能刷新策略:根据用户行为和网络状况动态调整刷新时机。
  2. 多因素认证集成:结合生物识别等技术,提供更安全的无感认证体验。
  3. 统一身份管理:在跨平台和跨设备场景下实现无缝的无感刷新。
  4. 隐私保护增强:在保证用户体验的同时,进一步加强用户隐私保护。

无感刷新机制通过智能的技术手段,解决了传统Token认证方式中用户需要频繁登录的问题,既提升了用户体验,又保证了系统的安全性。随着技术的不断进步,这种机制将在更多场景中得到应用,为用户带来更加便捷和安全的使用体验。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号