JWT生成Token实现单点登录

一、单点登录概述

单点登录(Single Sign On),简称为 SSO,是比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。不同于传统的单体应用,所有业务都在一个应用中,在分布式服务中,会有很多独立的项目,而这些项目又是有联系的,如A项目为购物车模块,B项目为订单模块,当我在向购物车加入商品的时候需要登录,而当我查询订单的时候也需要登录,那单点登录就是如果我登陆了购物车应用或者订单应用其中之一,再登陆其他的应用时便不需要登录。
如百度的新闻和百度贴吧。
在这里插入图片描述

二、实现方式

session广播方式
在这里插入图片描述
这种方式在少量应用的情况下是可以的,但是如果累计有几十个应用的话,每个应用都持有一份相同的session,这样就造成了内存资源的浪费,降低性能。

cookie+redis
在这里插入图片描述
这种方式当用户成功以后,生成一个唯一id值,然后将这个值和用户的信息存入到redis中,也可以设置过期时间,然后再通过cookie的方式将这个id推送给浏览器,这样当浏览器再访问其他需要登录的功能时就检查有没有该cookie,这种方式不用每个服务器都保存一份,减少了内存的消耗。

token方式

在这里插入图片描述
这种方式在用户登录成功以后以某种规则将用户的信息进行加密,然后通过拼接url的方式返回。

jwt介绍

刚才说了,用户登录成功以后以某种规则将用户的信息进行加密,然后通过拼接url的方式返回,那jwt就是一种处理该字符串的一种规则。jwt包含三部分,第一部分是头信息,主要为token的类型和使用的加密算法,第二部分为有效载荷,也就是用户的信息,第三部分为签名,可以防止内容被窜改。
在这里插入图片描述
jwt具体实现

引入依赖:

		 <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>

JWT工具类:

public class JwtUtils {
    
    

    public static final long EXPIRE = 1000 * 60 * 60 * 24; //token过期时间
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; //秘钥

    //生成token字符串的方法
    public static String getJwtToken(String id, String nickname){
    
    

        String JwtToken = Jwts.builder()
                .setHeaderParam("typ", "JWT") //设置jwt头信息
                .setHeaderParam("alg", "HS256")

                .setSubject("user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) //设置过期时间

                .claim("id", id)  //设置token主体部分 ,存储用户信息
                .claim("nickname", nickname)

                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .compact();

        return JwtToken;
    }

    /**
     * 判断token是否存在与有效
     * @param jwtToken
     * @return
     */
    public static boolean checkToken(String jwtToken) {
    
    
        if(StringUtils.isEmpty(jwtToken)) return false;
        try {
    
    
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 判断token是否存在与有效
     * @param request
     * @return
     */
    public static boolean checkToken(HttpServletRequest request) {
    
    
        try {
    
    
            String jwtToken = request.getHeader("token");
            if(StringUtils.isEmpty(jwtToken)) return false;
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 根据token字符串获取会员id
     * @param request
     * @return
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request) {
    
    
        String jwtToken = request.getHeader("token");
        if(StringUtils.isEmpty(jwtToken)) return "";
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String)claims.get("id");
    }
}

调用生成token方法查看控制台
在这里插入图片描述
这就是JWT规则给我们生成的token。

猜你喜欢

转载自blog.csdn.net/qq_43750656/article/details/106850791