
八.单点登录问题(JWT令牌的使用)
1.用户身份认证产生的问题
2.JWT令牌简介
3.JWT令牌的使用
八.单点登录问题(JWT令牌的使用)
1.用户身份认证产生的问题
①单一服务器
- 流程
一个web服务器,web服务器接受前端数据与数据库数据进行校验。然后返回存储该session的用户信息的cookie,用户下次请求时携带cookie即可,服务器只需通过cookie校验信息。
- 判断是否登录
cookie中携带用户信息,第二次发过来如果cookie的用户信息和数据库中相同,则已经登录。
缺点:
单点压力,无法扩展(多个web服务器返回不同coolie无法互通登录),需要使用session共享方案
②单点登录SSO(Single Sign On)模式
- 解决上述问题:用redis缓存存储分布式的cookie。有统一的登录认证服务。
- 流程
无论那个web服务器接受到访问请求先去认证服务查看是否登录,登录校验后存储在redis中,然后下一次接收到访问请求先查看redis中是否有用户身份信息,有则不需要登录。
- 判断是否登录
第一次生成token返回为key,用户信息为value,校验时通过key查redis中是否有value,有则登陆过无需登录。
- 缺点
认证服务器压力较大
③token模式
- 解决上述问题:利用令牌存储用户信息保存在用户本地,第一次访问授权服务器生成令牌返回给客户端,之后访问其他微服务只需检验令牌是否正确即可不用登录实现访问。
- 判断用户是否登录
JWT保存了用户信息和服务器端为每个用户信息生成的密码(客户端不知道),在所有微服务共享该密码,如果解析JWT后密码相同,则登录过。
- 缺点:
占用带宽,jwt技术生成字符串较长
2.JWT令牌简介
①令牌种类
- 透明令牌
不存储其他信息,只存储引用字符串,引用字符串用于指向具体服务器端的用户信息
- 自包含令牌(JWT)
JSON Web Tokens,包含了用户信息和独一无二的服务器端生成的密码,通过编码和解码来对比信息是否登录过。
②JWT令牌的简介
- 头
算法
- 有效载荷
数据
- 签名哈希
根据服务器端独一无二的密码编码
3.JWT令牌的使用
①引入pom
<dependencies><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.7.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>
③编码jwt
package com.atguigu.jwt;public class JwtTests {private static long tokenExpiration = 24*60*60*1000;private static String tokenSignKey = "atguigu123";@Testpublic void testCreateToken(){String token = Jwts.builder().setHeaderParam("typ", "JWT") .setHeaderParam("alg", "HS256") .setSubject("guli-user") .setIssuer("atguigu").setAudience("atguigu").setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) .setNotBefore(new Date(System.currentTimeMillis() + 20*1000)) .setId(UUID.randomUUID().toString()).claim("nickname", "Helen").claim("avatar", "1.jpg").signWith(SignatureAlgorithm.HS256, tokenSignKey).compact(); System.out.println(token);}
}
④解码jwt
@Test
public void testGetUserInfo(){String token = "jwt字符串";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();String subject = claims.getSubject();String issuer = claims.getIssuer();String audience = claims.getAudience();Date issuedAt = claims.getIssuedAt();Date expiration = claims.getExpiration();Date notBefore = claims.getNotBefore();String id = claims.getId();System.out.println(subject);System.out.println(issuer);System.out.println(audience);System.out.println(issuedAt);System.out.println(expiration);System.out.println(notBefore);System.out.println(id);;String nickname = (String)claims.get("nickname");String avatar = (String)claims.get("avatar");System.out.println(nickname);System.out.println(avatar);
}
未更新
未更新
未更新
未更新
未更新
未更新
未更新
未更新
未更新
未更新
未更新