JWT--token 认证

常见的认证方式

  • http basic auth: 最简单的每次都要认证用户名和密码,不安全、麻烦、所以不采用
  • cookie+session: 比较常用,但是比较费服务器空间,服务器需要为每个用户开辟session空间

image-20210317093722106

  • OAuth第三方授权:

image-20210317094721745

用户在访问虾米app时需要使用qq账号登陆,于是qq认证服务器让用户授权,用户授权通过后,qq服务器发一个令牌给虾米,虾米带着这个令牌去qq资源服务器获取用户的基本信息(昵称、头像、性别等),虾米再把信息展示给用户。

  • 基于Token的认证

image-20210317095412404

客户端在服务器端登陆成功以后,服务器会创建一个token,保存在redis中,并且把这个token发送给客户端。客户端下次访问资源时会自动携带这个token,服务器拿到token去redis中验证,如果验证通过就把信息进行返回。

token认证的优点:比http basic auth安全、比cookie节省服务器空间,比oauth认证要轻巧,应用场景也不同。

token的优点:

  • 可以不需要通过cookie来保存,让前端把token放到请求头里传递给后端,不受cookie的跨域限制。
  • token和uuid还是有区别的,因为可以直接通过token的解码来获取用户的部分信息。-- jwt 通过base64编码将用户信息编码成token,因此可以通过base64解码获取token中的用户信息

一、JWT

1.jwt介绍

Json web token 是一种存储和传输数据的标准。jwt由三个部分组成: 头部、负载、签名

1)头部

头部用来存放描述jwt的基本信息,比如类型、算法

{
  "alg": "HS256",
  "typ": "JWT"
}

使用base64编码后:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9,也就是说使用base64解码后能还原字符串信息

2)负载

分成了两种声明:

  • 公共的声明:存放一些标准的信息,固定的键
  • 私有的声明:存放自定义信息
{
  "sub": "use001",
  "name": "weixiang",
  "iat": 1516239022
}

3)签名

通过用户指定的盐,来生成签名,用于服务端的安全验证。但不能保证jwt中负载中数据的必然的安全。

image-20210317102227832

二、JWT的官方推荐类库-JJWT

1.引入依赖

<!--jjwt-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>

2.创建token

	@Test
    public void createToken(){
        //创建JWT对象
        JwtBuilder jwtBuilder = Jwts.builder()
            	.setId("1001")//设置公共参数id
                .setSubject("xiaowang")//设置对象名
                .setIssuedAt(new Date())//设置签发时间
                .signWith(SignatureAlgorithm.HS256, "qfjava");//设置签名

        //得到token
        String token = jwtBuilder.compact();
        System.out.println(token);

    }
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxMDAxIiwic3ViIjoieGlhb3dhbmciLCJpYXQiOjE2MTU5NDk2NjJ9.MSGqmONhNdxDG0XldhZQ1iXpY4IfU-PjmjS3MpHMb64

3.解析token,获取token中的数据

  /**
     * 解析token
     */
    @Test
    public void parseToken(){

        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxMDAxIiwic3ViIjoieGlhb3dhbmciLCJpYXQiOjE2MTU5NDk2NjJ9.MSGqmONhNdxDG0XldhZQ1iXpY4IfU-PjmjS3MpHMb64";
        Claims claims = Jwts.parser().setSigningKey("qfjava").parseClaimsJws(token).getBody();//设置签名
        System.out.println("id:"+claims.getId());//获取token中的数据
        System.out.println("subject:"+claims.getSubject());
        System.out.println("time:"+claims.getIssuedAt());

    }

4.设置token的超时时间

/**
     * 设置token的过期时间
     */
    @Test
    public void testExp(){

        long now = System.currentTimeMillis();
        long exp = now + 60*1000;//设置过期的时间的毫秒值
        Date expDate = new Date(exp);

        //创建JWT对象
        JwtBuilder jwtBuilder = Jwts.builder().setId("1001")//设置公共参数id
                .setSubject("xiaowang")//设置对象名
                .setIssuedAt(new Date())//设置签发时间
                .setExpiration(expDate)//过期的时间点
                .signWith(SignatureAlgorithm.HS256, "qfjava");//设置签名

        //得到token
        String token = jwtBuilder.compact();
        System.out.println(token);

    }

5.创建带自定义声明的token

	 /**
     * 创建token
     */
    @Test
    public void createCustomToken(){

        //创建JWT对象
        JwtBuilder jwtBuilder = Jwts.builder().setId("1001")//设置公共参数id
                .setSubject("xiaowang")//设置对象名
                .setIssuedAt(new Date())//设置签发时间
                .claim("role","student")
                .claim("class","java2007")
                .signWith(SignatureAlgorithm.HS256, "qfjava");//设置签名


        //得到token
        String token = jwtBuilder.compact();
        System.out.println(token);


    }


6.解析自定义声明的token

/**
     * 解析自定义声明的token
     */
    @Test
    public void parseClaimToken(){
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxMDAxIiwic3ViIjoieGlhb3dhbmciLCJpYXQiOjE2MTU5NTA0OTksInJvbGUiOiJzdHVkZW50IiwiY2xhc3MiOiJqYXZhMjAwNyJ9.dSiMUMpqvCJIZFVRRPO5tRho3ue2qCuEYQP0r2JrJvQ";
        Claims claims = Jwts.parser().setSigningKey("qfjava").parseClaimsJws(token).getBody();//设置签名
        System.out.println("role:"+claims.get("role"));
        System.out.println("class:"+claims.get("class"));
    }

posted @ 2021-07-21 14:43  牛奶配苦瓜  阅读(721)  评论(0编辑  收藏  举报