> 文章列表 > 8.单点登录问题(JWT令牌的使用)

8.单点登录问题(JWT令牌的使用)

8.单点登录问题(JWT令牌的使用)

八.单点登录问题(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><!-- JWT --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.7.0</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>

③编码jwt

package com.atguigu.jwt;public class JwtTests {//过期时间,毫秒,24小时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)) //20秒后可用.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);
}

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新