jwt鉴权

背景:

一个普通项目配置在一台服务器上并发性并不高,但是像一些大型的电商 门户网站,每一天的访问量过千万,也就是说在同一时间可能会有近万人访问。一台服务器的并发量就难以满足。这个时候人们 就想到了利用分布式架构。采用集群的方式来提高并发性。

一般会配一个nginx集群来进行反向代理,使得多个服务器上分担的压力均衡,达到负载均衡。如图

这个时候就存在一个问题,传统方式我们登陆注册需要将登陆后的用户信息存储在session中,后面需要操作只需要在session中取就好了。但是现在每个服务器对应不同的会话,也就说session域也不一样,比如上图我第一次访问被nginx通知我去找第一个服务器,登陆以后将登陆信息存储在第一个session中,但第二次我访问同样的网站,又被分到第二个服务器上,这个服务器并没有上次登陆的信息,也取不到第一个session中的信息,那么还得登陆一下。

这样问题就来了:假如每次访问,请求被转发给不同的服务器,那么就得不停的登陆,这个体验感就很差,也没有网站这样做。

解决session共享

1、session复制

最简单的方式也容易想到,无论在哪个服务器上登陆,都会把session信息复制到另外的服务器上,这样一来无论被转发的哪个服务器,session信息都会存在。但是这样做弊端也很明显。

如果我有100个服务器,也就意味着每次登陆存入session的信息会被查到并复制到剩下的99个服务器上,而且还需要随时监视每个服务器上的用户登陆情况,既浪费了空间,效率也非常低。

2、session黏着

利用算法,将每个用户访问的服务器固定下来,比如下图中

利用hash法,将每个访问者的id对服务器总数取余,余数对应的服务器的s_id的请求就会被转发到指定的服务器上。也就是说每个访问者访问该网站被分到服务器是固定的,这样一来就不存在session中的信息不一致的情况。

这样做也会存在一些弊端,比如当服务器总数发生改变的时候,进行hash的结果也会发生变化,导致session存入的访问者登陆信息又不一致。

3、session共享

将登陆信息存入一个固定的session服务器(多用redis数据库)每次读写信息,只需要找session服务器即可。这样就可以达到session共享,但是存在跨域的问题。

4、不使用session的方式----jwt (json web token)

利用token(令牌)登陆成功以后会创建一个令牌,下一次访问只需要带着这个令牌去,就不需要再次登陆,这样种方式也被称作鉴权

JJWT API

导入maven依赖包

 <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-impl</artifactId>
        <version>0.10.5</version>
 </dependency>

 <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-jackson</artifactId>
        <version>0.10.5</version>
 </dependency>

生成token

String token = Jwts.builder()
	.claim("sub", "内容部分")
	.claim("exp", "时间的秒值") 
     //这里利用HS256对称算法              //此字符串为密钥
	.signWith(SignatureAlgorithm.HS256, "ZYUf0Oym0Lhi9V7f6ML6tXcv0HvGH7YnuhbGhk8Y/+U=")
	.compact();

sub是登陆成功以后的内容部分,也就是需要存储的内容信息

exp设置令牌过期时间

除了上述的设置方式,还可以这样设置

String token = Jwts.builder()
	.setSubject("内容部分") // 等价于claims("sub", "内容部分")
	.setExpiration(new Date(System.currentTimeMillis()+60*1000)) // 设置 1 分钟后过期
	.signWith(SignatureAlgorithm.HS256, "ZYUf0Oym0Lhi9V7f6ML6tXcv0HvGH7YnuhbGhk8Y/+U=")
	.compact();

验证令牌

Jwts.parser()   // 设置秘钥
.setSigningKey("ZYUf0Oym0Lhi9V7f6ML6tXcv0HvGH7YnuhbGhk8Y/+U=").parse("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiZXhwIjoiMTU1MjcxNTU1MyJ9.4rvHxsGNiZzuukQ2L-oT9uqKFymr94-371Am05qY7BQ");//传入令牌

jwts.parse()方法会有一个返回值Jwt类。可以通过jwt的get()获取密钥中的信息,如sub exp 或自定义的等等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值