专栏名称: 芋道源码
纯 Java 源码分享公众号,目前有「Dubbo」「SpringCloud」「Java 并发」「RocketMQ」「Sharding-JDBC」「MyCAT」「Elastic-Job」「SkyWalking」「Spring」等等
目录
相关文章推荐
芋道源码  ·  秒懂双亲委派机制 ·  3 天前  
芋道源码  ·  《黑神话 . 悟空》员工工资收入曝光 ·  3 天前  
芋道源码  ·  一款高颜值、企业级的开源监控分析系统 ·  5 天前  
Java编程精选  ·  人人影视创始人致歉:出来一个月,恍如昨日 ·  1 周前  
51好读  ›  专栏  ›  芋道源码

token是用来鉴权的,那session是用来干什么的?

芋道源码  · 公众号  · Java  · 2024-10-16 09:30

正文

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:juejin.cn/post/
7383017171180568630


使用JWT进行用户认证和授权,而Session在一定程度上起到了辅助作用。让我们详细讨论JWT和Session在这种结合模式中的各自作用以及为什么需要Session。

JWT的作用

  • 用户认证: JWT包含了用户的身份信息和权限信息,客户端每次请求时将JWT发送给服务器,服务器通过验证JWT来确认用户身份。
  • 无状态性: JWT不需要在服务器端存储用户会话信息,因此服务器可以是无状态的,便于扩展和负载均衡。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

Session的作用

  • 附加的安全层: 即使JWT是无状态的,但在某些应用场景中,仅依赖JWT可能存在一些安全问题,例如Token的泄露或滥用。Session可以作为一个额外的安全层,确保Token即使有效,也必须在服务器的Session管理器中存在对应的会话。
  • 管理Token的生命周期: 通过Session,可以更方便地管理Token的生命周期,例如强制用户重新登录、手动注销Token等操作。
  • 控制“记住我”功能: 如果用户选择了“记住我”选项,Session可以记录这个状态,并在JWT过期后,通过Session来决定是否允许继续使用旧的Token。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

为什么需要创建Session

尽管JWT可以在无状态环境中使用,但Session的引入带来了以下好处:

  • 防止Token滥用: 通过在服务器端验证Session,可以确保即使Token有效,也必须是经过服务器端认证的,从而防止Token被恶意使用。
  • 支持用户主动注销: 当用户选择注销时,可以直接删除服务器端的Session记录,确保Token即使没有过期,也无法再被使用。
  • 提供更精细的控制: 通过Session,可以实现更精细的权限控制和用户状态管理,例如强制下线、会话过期时间控制等。
  • 状态追踪: 在某些场景下,追踪用户状态是必要的,例如监控用户的活跃度、登录历史等,这些信息可以通过Session进行管理。

结合JWT和Session的优势

结合使用JWT和Session,可以同时利用两者的优点,实现安全性和扩展性的平衡:

  • 无状态认证: JWT可以实现无状态认证,便于系统的水平扩展和负载均衡。
  • 状态管理和安全性: Session可以提供额外的状态管理和安全性,确保Token的使用更加安全可靠。

代码示例

以下是一个简化的代码示例,展示了如何在用户登录时创建JWT和Session:

public LoginResponse login(String username, String password) throws AuthException {
    // 验证用户名和密码
    User user = userService.authenticate(username, password);
    if (user == null) {
        throw new AuthException("Invalid username or password");
    }
    
    // 生成JWT Token
    String token = createJwt(user.getId(), user.getRoles());
    
    // 创建会话
    sessionManagerApi.createSession(token, user);
    
    // 返回Token
    return new LoginResponse(token);
}

public void createSession(String token, User user) {
    LoginUser loginUser = new LoginUser();
    loginUser.setToken(token);
    loginUser.setUserId(user.getId());
    loginUser.setRoles(user.getRoles());
    
    sessionManagerApi.saveSession(token, loginUser);
}

在请求验证时,首先验证JWT的有效性,然后检查Session中是否存在对应的会话:

@Override
public DefaultJwtPayload validateToken(String token) throws AuthException {
    try {
        // 1. 先校验jwt token本身是否有问题
        JwtContext.me().validateTokenWithException(token);

        // 2. 获取jwt的payload
        DefaultJwtPayload defaultPayload = JwtContext.me().getDefaultPayload(token);

        // 3. 如果是7天免登陆,则不校验session过期
        if (defaultPayload.getRememberMe()) {
            return defaultPayload;
        }

        // 4. 判断session里是否有这个token
        LoginUser session = sessionManagerApi.getSession(token);
        if (session == null) {
            throw new AuthException(AUTH_EXPIRED_ERROR);
        }

        return defaultPayload;
    } catch (JwtException jwtException) {
        if (JwtExceptionEnum.JWT_EXPIRED_ERROR.getErrorCode().equals(jwtException.getErrorCode())) {
            throw new AuthException(AUTH_EXPIRED_ERROR);
        } else {
            throw new AuthException(TOKEN_PARSE_ERROR);
        }
    } catch (io.jsonwebtoken.JwtException jwtSelfException) {
        throw new AuthException(TOKEN_PARSE_ERROR);
    }
}

总结

在这个场景中,JWT用于无状态的用户认证,提供便捷和扩展性;Session作为辅助,提供额外的安全性和状态管理。通过这种结合,可以充分利用两者的优点,确保系统既具备高扩展性,又能提供细致的安全控制。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)