JWT在java中的应用以及分布式应用下登录校验

简介:讲解单机和分布式应用下登录校验,session共享,分布式缓存使用
1、单机tomcat应用登录检验
            sesssion保存在浏览器和应用服务器会话之间
            用户登录成功,服务端会保证一个session,当然会给客户端一个sessionId,
            客户端会把sessionId保存在cookie中,每次请求都会携带这个sessionId
​
2、分布式应用中session共享
            真实的应用不可能单节点部署,所以就有个多节点登录session共享的问题需要解决
            1)tomcat支持session共享,但是有广播风暴;用户量大的时候,占用资源就严重,不推荐
            2)使用redis存储token:
                    服务端使用UUID生成随机64位或者128位token,放入redis中,然后返回给客户端并存储在cookie中
                    用户每次访问都携带此token,服务端去redis中校验是否有此用户即可
微服务下登录检验解决方案 JWT讲解(推荐)
1、JWT 是一个开放标准,它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。
            JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名
​
            简单来说,就是通过一定规范来生成token,然后可以通过解密算法逆向解密token,这样就可以获取用户信息
            {
                id:888,
                name:'小D',
                expire:10000
            }
            
            funtion 加密(object, appsecret){
                xxxx
                return base64( token);
            }
​
            function 解密(token ,appsecret){
​
                xxxx
                //成功返回true,失败返回false
            }
​
            优点:
                1)生产的token可以包含基本信息,比如id、用户昵称、头像等信息,避免再次查库
​
                2)存储在客户端,不占用服务端的内存资源
​
            缺点:
                token是经过base64编码,所以可以解码,因此token加密前的对象不应该包含敏感信息
                如用户权限,密码等
​
2、JWT格式组成 头部、负载、签名
           header+payload+signature
​
           头部:主要是描述签名算法
           负载:主要描述是加密对象的信息,如用户的id等,也可以加些规范里面的东西,如iss签发者,exp 过期时间,sub 面向的用户
           签名:主要是把前面两部分进行加密,防止别人拿到token进行base解密后篡改token
​
3、关于jwt客户端存储
            可以存储在cookie,localstorage和sessionStorage里面
JWT在java(Springboot)中的应用
  1. 引入相关依赖并开发JWT工具类
			<!-- JWT相关 -->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.7.0</version>
            </dependency>
  1. 封装 JWT生成和解析token的工具类
package com.itzhongzi.videoedu.utils;

import com.itzhongzi.videoedu.domain.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtils {

    /*
     * 发行者
     * */
    public static final String SUBJECT = "itzhongzi";
    /*
     * 过期时间为 一周
     * */
    public static final long EXPIRE = 1000 * 60 * 60 * 24 * 7;
    /*
     * 密钥
     * */
    public static final String APPSECRET = "it666";

    /**
     * 生成 JWT
     *
     * @param user
     * @return
     */
    public static String geneJsonWebToken(User user) {

        if (user == null || user.getId() == null || user.getName() == null || user.getHeadImg() == null) {
            return null;
        }
        String token = Jwts.builder().setSubject(SUBJECT)
                .claim("id", user.getId())
                .claim("name", user.getName())
                .claim("image", user.getHeadImg())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                .signWith(SignatureAlgorithm.HS256, APPSECRET)
                .compact();

        return token;
    }

    /**
     * 校验 token
     *
     * @param token
     * @return
     */
    public static Claims checkJWT(String token) {
        try {
            final Claims claims = Jwts.parser().setSigningKey(APPSECRET)
                    .parseClaimsJws(token)
                    .getBody();
            return claims;
        } catch (Exception e) { }
        return null;
    }

}

  1. 测试 工具类

    @Test
    public void testJWT(){
        User user = new User();
        user.setId(999);
        user.setHeadImg("www.itzhongzi.com");
        user.setName("it");


        String token = JwtUtils.geneJsonWebToken(user);
        System.out.println("token: " + token);


    }

    @Test
    public void testCheck(){
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJpdHpob25nemkiLCJpZCI6OTk5LCJuYW1lIjoiaXQiLCJpbWFnZSI6Ind3dy5pdHpob25nemkuY29tIiwiaWF0IjoxNTc2MDU1MjM0LCJleHAiOjE1NzY2NjAwMzR9.VH8f6579SJk74HaPGfzgp5tyKVgOwjmu8E96QoR3OVs";
        Claims claims = JwtUtils.checkJWT(token);
        if(claims != null) {
            System.out.println(claims);
            String name = (String) claims.get("name");
            String img = (String) claims.get("image");
            int id = (Integer) claims.get("id");
            System.out.println(name);
            System.out.println(img);
            System.out.println(id);
        } else {
            System.out.println("解密失败,非法token");
        }
  1. 测试结果
    在这里插入图片描述
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ITzhongzi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值