前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >面试官:Session和JWT有什么区别?

面试官:Session和JWT有什么区别?

作者头像
用户11397231
发布于 2024-12-27 00:21:27
发布于 2024-12-27 00:21:27
13900
代码可运行
举报
文章被收录于专栏:算法算法
运行总次数:0
代码可运行

引言

在用户和服务器之间建立认证状态是Web开发中常见的需求。SessionJWTJSON Web Token)是两种常用的机制,但它们在工作原理、存储方式和安全性等方面存在差异。

什么是JWT?

JWT是一种开放标准(RFC 7519),用于在网络上安全传输信息的简洁、自包含的方式。它通常被用于身份验证和授权机制。JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

  • 头部(Header):包含了关于生成该JWT的信息以及所使用的算法类型。
  • 载荷(Payload):包含了要传递的数据,例如身份信息和其他附属数据。JWT官方规定了7个字段,可供使用:
    • iss (Issuer):签发者。
    • sub (Subject):主题。
    • aud (Audience):接收者。
    • exp (Expiration time):过期时间。
    • nbf (Not Before):生效时间。
    • iat (Issued At):签发时间。
    • jti (JWT ID):编号。
  • 签名(Signature):使用密钥对头部和载荷进行签名,以验证其完整性。

JWT优点分析

相较于传统的基于会话(Session)的认证机制,JWT具有以下优势:

  • 无需服务器存储状态:服务器无需存储任何会话状态信息,所有的认证和授权信息都包含在JWT中。
  • 跨域支持JWT可以轻松地在多个域之间进行传递和使用,实现跨域授权。
  • 适应微服务架构:在微服务架构中,很多服务是独立部署并且可以横向扩展的,这就需要保证认证和授权的无状态性。
  • 自包含JWT包含了认证和授权信息,以及其他自定义的声明,这些信息都被编码在JWT中。
  • 扩展性JWT可以被扩展和定制,可以按照需求添加自定义的声明和数据。

JWT基本使用

Java开发中,可以借助JWT工具类来方便的操作JWT,例如HuTool框架中的JWTUtil

3.1 添加HuTool框架依赖

pom.xml中添加以下依赖:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.16</version>
</dependency>
3.2 生成Token
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Map<String, Object> map = new HashMap<String, Object>() {
    private static final long serialVersionUID = 1L;
    {
        put("uid", Integer.parseInt("123")); // 用户ID
        put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15); // 过期时间15天
    }
};
String token = JWTUtil.createToken(map, "服务器端秘钥".getBytes());
3.3 验证和解析Token

验证Token的示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2MjQwMDQ4MjIsInVzZXJJZCI6MSwiYXV0aG9yaXRpZXMiOlsiUk9MRV_op5LoibLkuozlj7ciLCJzeXNfbWVudV8xIwiUk9MRV_op5LoibLkuIDlj7ciLCJzeXNfbWVudV8yIl0sImp0aSI6ImQ0YzVlYjgwLTA5ZTctNGU0ZC1hZTg3LTVkNGI5M2FhNmFiNiIsImNsaWVudF9pZCI6ImhhbmR5LXNob3AifQ.aixF1eKlAKS_k3ynFnStE7-IRGiD5YaqznvK2xEjBew";
JWTUtil.verify(token, "123456".getBytes());

解析Token的示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9.U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA";
final JWT jwt = JWTUtil.parseToken(rightToken);
jwt.getHeader(JWTHeader.TYPE);
jwt.getPayload("sub");
3.4 代码实战

在登录成功之后,生成Token的示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 登录成功,使用 JWT 生成 Token
Map<String, Object> payload = new HashMap<String, Object>() {
    private static final long serialVersionUID = 1L;
    {
        put("uid", userinfo.getUid());
        put("manager", userinfo.getManager());
        // JWT 过期时间为 15 天
        put("exp", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15);
    }
};
String token = JWTUtil.createToken(payload, AppVariable.JWT_KEY.getBytes());

例如在Spring Cloud Gateway网关中验证Token的实现代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.example.common.AppVariable;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 登录过滤器(登录判断)
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    // 排除登录验证的 URL 地址
    private String[] skipAuthUrls = {"/user/add", "/user/login"};

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 当前请求的 URL
        String url = exchange.getRequest().getURI().getPath();
        for (String item : skipAuthUrls) {
            if (item.equals(url)) {
                // 继续往下走
                return chain.filter(exchange);
            }
        }
        ServerHttpResponse response = exchange.getResponse();
        // 登录判断
        List<String> tokens =
                exchange.getRequest().getHeaders().get(AppVariable.TOKEN_KEY);
        if (tokens == null || tokens.size() == 0) {
            // 当前未登录
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // token 有值
        String token = tokens.get(0);
        // JWT 效验 token 是否有效
        boolean result = false;
        try {
            result = JWTUtil.verify(token, AppVariable.JWT_KEY.getBytes());
        } catch (Exception e) {
            result = false;
        }
        if (!result) {
            // 无效 token
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        } else { // 判断 token 是否过期
            final JWT jwt = JWTUtil.parseToken(token);
            // 得到过期时间
            Object expObj = jwt.getPayload("exp");
            if (expObj == null) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            long exp = Long.parseLong(expObj.toString());
            if (System.currentTimeMillis() > exp) {
                // token 过期
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
                        }
    }
    return chain.filter(exchange);
}

@Override
public int getOrder() {
    // 值越小越早执行
    return 1;
}
}

JWT实现原理

JWT本质上是将秘钥存放在服务器端,并通过某种加密手段进行加密和验证的机制。加密签名=某加密算法(header+payload+服务器端私钥),因为服务端私钥别人不能获取,所以JWT能保证自身其安全性。

Session VS JWT

SessionJWT的区别主要有以下几点:

  • 工作原理不同Session机制依赖于服务器端的存储,而JWT是一种无状态的认证机制,它通过在客户端存储令牌(Token)来实现认证。
  • 存储方式不同Session信息存储在服务器端,而JWT信息存储在客户端。
  • 有效期和灵活性不同Session的有效期通常由服务器控制,而JWT的有效期可以在令牌生成时设置,并且可以在客户端进行缓存和重复使用。

总结

SessionJWT各有优势和适用场景。Session适合于需要频繁更改用户状态和服务器资源充足的场景,而JWT适合于分布式系统、微服务架构以及需要跨域认证的场景。选择合适的认证机制,可以提高系统的安全性、可扩展性和维护性。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验