实现令牌技术

目录

令牌技术

实现令牌的方式

JWT令牌

JWT令牌的生成和校验

1.引入JWT令牌的依赖

2.生成令牌

3.校验令牌


给一个场景:实现登录

传统思路:

• 登陆页面把用户名密码提交给服务器.

• 服务器端验证用户名密码是否正确, 并返回校验结果给后端

• 如果密码正确, 则在服务器端创建 Session . 通过 Cookie 把 sessionId 返回给浏览器.

问题: 集群环境下无法直接使用Session。

1.session存在服务器中,服务器重启,session丢失,用户需要重新登录。

2.用户第一次请求,分配在服务器1,session存在服务器1上。用户第二次请求,分配在服务器2,服务器2没有用户的session,校验失败,认为用户没有登录,让用户重新登录。

解决方案:

1.session存储在一个公用机器(或者缓存中)

2.token(常用)

token:带有一定信息的字符串,token是客户端进行访问时携带的;token不能伪造;token不是用来加密,是用来防止篡改。

令牌技术

令牌其实就是⼀个用户身份的标识

使用令牌技术解释场景:

  1. 用户登录 用户登录请求, 经过负载均衡, 把请求转给了第一台服务器, 第一台服务器进行账号密码验证, 验证成功后, 生成⼀个令牌, 并返回给客户端。
  2. 客户端收到令牌之后, 把令牌存储起来. 可以存储在Cookie中, 也可以存储在其他的存储空间(比如 localStorage)
  3.  查询操作 用户登录成功之后, 携带令牌继续执行查询操作, 比如查询博客列表. 此时请求转发到了 第二台机器, 第二台机器会先进行权限验证操作.。服务器验证令牌是否有效, 如果有效, 就说明用户已经执行了登录操作, 如果令牌是无效的, 就说明用户之前未执行登录操作。

令牌的优缺点

优点: 1.解决了集群环境下的认证问题

         2.减轻服务器的存储压力(无需在服务器端存储)

缺点: 1.需要自己实现(包括令牌的生成, 令牌的传递, 令牌的校验)

当前企业开发中, 解决会话跟踪使用最多的方案就是令牌技术

实现令牌的方式

JWT令牌

JWT全称: JSON Web Token

官网: JSON Web Tokens - jwt.io

JSON Web Token(JWT) 用于客户端和服务器之间传递安全可靠的信息。其本质是一个token, 是一种紧凑的URL安全方法。

JWT令牌的生成和校验
1.引入JWT令牌的依赖
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
 <groupId>io.jsonwebtoken</groupId>
 <artifactId>jjwt-api</artifactId>
 <version>0.11.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
 <groupId>io.jsonwebtoken</groupId>
 <artifactId>jjwt-impl</artifactId>
 <version>0.11.5</version>
 <scope>runtime</scope>
</dependency>
<dependency>
 <groupId>io.jsonwebtoken</groupId>
 <artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred--> 
 <version>0.11.5</version>
 <scope>runtime</scope>
</dependency>
2.生成令牌
public class JwtUtilTest {
    //过期时间,30分钟
    private static final long expiration=30*60*1000;
    //1.生成token
    //2.验证token
    @Test
    public void getToken(){
        Key key= Keys.hmacShaKeyFor(Decoders.BASE64.decode("asddfghhjjzzzzzzaqwexfgff"));//签名的编码方式
        Map<String,Object> claim=new HashMap<>();
        claim.put("id",5);
        claim.put("name","zhangsan");
        //setClaims()自定义载荷(要存储的信息)
        String token=Jwts.builder()
                            .setClaims(claim)//生成载荷
                            .setExpiration(new Date(System.currentTimeMillis()+expiration))//生成过期时间
                            .signWith(key)//生成签名
                            .compact();//生成token
        System.out.println(token);
    }
}

运行:

加长字符串长度,得到token,将token解析:

自动随机生成key

 @Test
    public void genKey(){
        //随机生成一个key
        SecretKey secretKey= Keys.secretKeyFor(SignatureAlgorithm.HS256);
        String key = Encoders.BASE64.encode(secretKey.getEncoded());
        System.out.println(key);
    }

把这个生成的key带入上面,位数不会出现错误,即可生成token。

3.校验令牌

完成了令牌的生成, 我们需要根据令牌, 来校验令牌的合法性(以防客户端伪造)

    //校验令牌
    @Test
    public void parseToken(){
        String token ="eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiemhhbmdzYW4iLCJpZCI6NSwiZXhwIjoxNzA5MTk2MjE2fQ.8Kh05VSkgmXl2A_UtCU0GWlIVlNDApzpQ6wSMOoCsQ4";
        JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();
        Claims body = build.parseClaimsJws(token).getBody();
        System.out.println(body);
    }
  • 28
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Roylelele

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

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

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

打赏作者

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

抵扣说明:

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

余额充值