JWT(JSON Web Token)

目录

什么是JWT?

为什么要用JWT呢?

总结优点

什么是Token?

Token有什么用?

依赖

JWT工具类

JWT拦截器

配置JWT拦截器


什么是JWT?

JWT就是一种 基于令牌的身份验证和授权机制,它可以安全地在客户端和服务器之间传输信息

        具体来说,JWT框架提供了一种将用户身份信息(例如用户名、用户ID等)转换为数字签名令牌的方法,这个数字签名令牌可以在网络上安全地传输,然后在服务器端验证并授权。

        当然你可以这样理解,JWT就是古代的帝王,他颁发一个了金牌(token),这个令牌的真假一般人看不出来,它有特殊的鉴别方法(加密),只有各个地方的官员(不同的服务器)知道如何鉴别,公主(客户端)带着这个金牌去地方游玩时,想要获得地方官员的帮助(发送请求),这时官员(服务器)就会进行验证,确定其真假后(解密),就会给予帮助(对客户端进行响应)

为什么要用JWT呢?

验证用户的身份,对用户进行授权,例如访问某些受限资源

可能有的人就要说了,我们可以使用拦截器、数据库权限字段和Session这些方式来实现身份验证和授权功能。这些方式是可行的,但是,与JWT相比,它们存在一些局限性,在一些场景下可能不太适用,需要使用JWT来实现身份验证和授权。比如:

跨域访问:在跨域访问的场景中,由于浏览器的同源策略限制,无法使用Session来进行身份验证和授权。而JWT是基于JSON Web Token标准实现的,可以在跨域访问的场景中使用。

分布式系统:在分布式系统中,如果使用Session进行身份验证和授权,需要将Session存储在共享存储中,才能在不同的服务器之间共享Session信息。这样会增加系统的复杂度和开发成本。而JWT是基于令牌的身份验证和授权机制,可以在不同的服务器之间共享令牌信息,从而简化系统的设计和实现。

无状态API:在设计RESTful API时,为了提高API的可伸缩性和性能,通常会采用无状态的设计方式。这样,服务器不需要在自己的内存中保存任何会话信息。而JWT是一种无状态的身份验证和授权机制,可以很好地支持无状态API的设计和实现。

总结优点

无状态JWT本身是无状态的,即服务器不需要在自己的内存中保存任何会话信息。这样可以减少服务器的压力,使得服务器可以更容易地水平扩展。
跨语言JWT是基于JSON标准实现的(用JSON格式来定义令牌的结构和内容),因此可以在多种编程语言中使用。这使得JWT可以在不同的应用程序之间共享身份验证和授权信息。
安全性高JWT使用数字签名来验证令牌的合法性,因此可以防止令牌被篡改。此外,JWT还可以通过加密来保护令牌的机密信息。

什么是Token?

Token(即令牌)是一种用于身份验证和授权的凭证,它是一段字符串,通常是由服务器生成的。Token可以用于验证用户的身份,授权用户访问系统中的资源或执行某些操作。

Token有什么用?

用户身份验证

当用户登录系统时,服务器会验证用户的身份,并生成一个Token,将其返回给客户端。客户端在后续的请求中需要携带这个Token,服务器在验证Token的有效性后,才会对请求进行响应。

API访问授权

当客户端需要访问某个API时,服务器可以要求客户端提供Token,以验证客户端的身份和授权信息。如果客户端的Token有效,则服务器会授权其访问API,否则会拒绝其访问请求。

服务间通信

在分布式系统中,各个服务之间需要进行身份验证和授权,以保证系统的安全性和完整性。Token可以用于在服务之间传递身份验证和授权信息,确保服务之间的通信安全可靠。


不多BB了,直接上 SpringBoot集成JWT 的代码~

依赖

<dependency>
   <groupId>com.auth0</groupId>
   <artifactId>java-jwt</artifactId>
   <version>3.19.2</version>
</dependency>

JWT工具类

创建令牌

/**创建令牌 */
public class CreateToken {
    private  static final  long EXPIRE_TIME=1000*60*60;
    //秘钥
    public static  final String TOKEN_SECRET="13cd761e-8805-4294-8641-fc28fc3120a7";
    public static String getToken(String json) {
        //过期时间
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        //私钥及加密算法
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        //设置头信息
        HashMap<String, Object> header = new HashMap<>(2);
        header.put("typ", "JWT");
        header.put("alg", "HS256");
        //附带username和userID生成签名,token变量将保存生成的JWT字符串
        String token= JWT.create().withHeader(header)
                .withClaim("info",json)
                .withExpiresAt(date).sign(algorithm);
        return token;
    }

}

创建验证器

/**JWT验证器*/
public class Verifier {
    public static ResultTokenVo verifierJwt(String token){
/*创建一个HMAC256加密算法的对象,并设置了加密密钥CreateToken.TOKEN_SECRET。
这个密钥是在创建JWT时使用的密钥,用于对JWT进行签名和加密。在验证JWT时,需要
使用相同的密钥进行解密和验证。*/
        Algorithm algorithm = Algorithm.HMAC256(CreateToken.TOKEN_SECRET);
        String info="";
/*建了一个JWTVerifier对象,用于对JWT进行验证。它使用algorithm参数指定的
加密算法和密钥进行验证,即只有使用相同的密钥和算法才能解密和验证JWT。*/
        JWTVerifier verifier = JWT.require(algorithm).build();
        ResultTokenVo vo=new ResultTokenVo();
        try {
/**认证token */
/*用verifier对象对JWT进行验证,即解密并验证JWT的签名和过期时间等信息。
如果JWT验证通过,那么会返回一个DecodedJWT对象,包含了JWT的所有信息,
如签发者、过期时间、负载等。*/
            DecodedJWT jwt = verifier.verify(token);
/**取token中的信息 */
/*从JWT中获取info字段的值,并转换为字符串类型。这个字段通常用于存储一些额外的信息,如用户信息、权限信息等。*/
            info=jwt.getClaim("info").asString();
            vo.setTag(1);//验证通过,设置tag值
            vo.setJson(info);//额外信息
        }catch (Exception e){
            vo.setTag(0);
        }
//返回ResultTokenVo对象,可以根据ResultTokenVo对象的tag属性来判断JWT的验证结果
        return vo;
    }
}

JWT拦截器

//交给spring容器管理
@Component
public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        //对token进行验证
        ResultTokenVo resultTokenVo = Verifier.verifierJwt(token);
        //验证成功
        if (resultTokenVo.getTag() == 1) {
            /*将json属性的值(即JWT中包含的额外信息)解析为一个JSON对象,以便
            获取其中的具体字段值*/
            JSONObject jsonObject = JSONObject.parseObject(resultTokenVo.getJson());
            /*将JSON对象中名为userName的属性值保存到HTTP请求的属性中,以便
            在后续的请求处理中使用*/
            request.setAttribute("userName", jsonObject.get("userName"));
            return HandlerInterceptor.super.preHandle(request, response, handler);
        //验证失败
        } else {
            //返回客户端 相应的信息
            PrintWriter p = new PrintWriter("{'tag':'0'}");
            p.flush();
            p.close();
            return false;
        }
    }
}

配置JWT拦截器

@Component
public class JWTConfig implements WebMvcConfigurer {
    //注入自定义的拦截器
    @Autowired
    private JWTInterceptor jwtInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /*向拦截器链中添加jwtInterceptor对象,并设置其拦截的路径为/order/**,
        表示所有以/order开头的请求都需要进行JWT验证。*/
        registry.addInterceptor(jwtInterceptor)
                .addPathPatterns("/order/**");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BroRiver

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值