JWT-认证

本文深入探讨了JSON Web Token (JWT) 的工作原理,包括它的四个阶段,以及它在身份验证、跨域访问、无状态性和性能优化等方面的优势。通过实例展示了如何使用jjwt库创建和解析JWT,以及如何存储自定义信息。JWT作为现代Web应用的身份验证机制,简化了前后端分离的场景下用户信息的传递。
摘要由CSDN通过智能技术生成

JWT

4阶段的知识, JSON WEB TOEKN , json是指类型, 是个字符串, web 用于web请求, token就是令牌! 身份证!

什么时候出现的这个?? 登录成功 后! 发送到你的浏览器, 你可以自己定义存在什么地方!然后每次发送后台请求的时候, 在请求头中携带着token传到后端!后端解析token,拿到用户信息!

jwt进行token auth 认证! 取消 账号密码明文的认证方式!

前后端分离! cookie 是无法获取到后端的session信息! 那么我们后端如何获取用户登录后的信息?

JWT有什么好处?

1、支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输.

2、无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.

4、更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可.(居于前面两点得出这个更适用于CDN内容分发网络)

5、去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可.(这个似乎也在继续说前面第一点和第二点的好处。。。)

6、更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。

7、CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。(如果token是用cookie保存,CSRF还是需要考虑,一般建议使用1、在HTTP请求中以参数的形式加入一个服务器端产生的token。或者2.放入http请求头中也就是一次性给所有该类请求加上csrftoken这个HTTP头属性,并把token值放入其中)
ps:后面会推出一些常见的网络安全的处理

8、性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析要费时得多.

9、不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理.(知识面太窄,不是太明白这个的意思)

10、基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft).

快速入门

1.token的创建

(1)创建maven工程,引入依赖

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

(2)创建类CreateJwtTest,用于生成token

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

/**
 * @author: mayuhang  <br/>
 * Date: 2021/4/29:1:45  <br/>
 * Description:
 */
public class CreateJwtTest {
        public static void main(String[] args) {
            JwtBuilder builder= Jwts.builder().setId("888")
                    .setSubject("管理员")
                    .setIssuedAt(new Date())
                    .signWith(SignatureAlgorithm.HS256,"woniuxy");
            System.out.println( builder.compact() );
        }
}

(3)测试运行,输出如下:

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLnrqHnkIblkZgiLCJpYXQiOjE2MTk2MzIwMzJ9.5de6yHqZn7SMBduX9Xxu04w4WfREjyRLp5e9iqzSnjE

2.token的解析

我们刚才已经创建了token ,在web应用中这个操作是由服务端进行然后发给客户端,客户端在下次向服务端发送请求时需要携带这个token(这就好像是拿着一张门票一样),那服务端接到这个token 应该解析出token中的信息(例如用户id),根据这些信息查询数据库返回相应的结果。
创建ParseJwtTest

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

import java.io.UnsupportedEncodingException;

/**
 * @author: mayuhang  <br/>
 * Date: 2021/4/29:1:48  <br/>
 * Description:
 */
public class ParseJwtTest {
    public static void main(String[] args) {
        String token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiJBRE1JTiIsImlhdCI6MTYxOTYzMjQ3NH0.-TJRtXOjhjoU1oD7Y1VLAp2dSQeaVK7aBzRj0ZtTfPw";
        Claims claims =
                Jwts.parser().setSigningKey("woniuxy").parseClaimsJws(token).getBody();
        System.out.println("id:"+claims.getId());
        System.out.println("subject:"+claims.getSubject());
        System.out.println("IssuedAt:"+claims.getIssuedAt());
    }
}

3.自定义claims

我们刚才的例子只是存储了id和subject两个信息,如果你想存储更多的信息(例如角色)可以定义自定义claims
(1) 创建CreateJwtTest3,并存储指定的内容

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

/**
 * @author: mayuhang  <br/>
 * Date: 2021/4/29:1:45  <br/>
 * Description:
 */
public class CreateJwtTest {
        public static void main(String[] args) {
            //为了方便测试,我们将过期时间设置为1分钟
            long now = System.currentTimeMillis();//当前时间
            long exp = now + 1000*60;//过期时间为1分钟
            JwtBuilder builder= Jwts.builder().setId("888")
                    .setSubject("ADMIN")
                    .setIssuedAt(new Date())
                    .signWith(SignatureAlgorithm.HS256,"woniuxy")
                    .setExpiration(new Date(exp))
                    .claim("roles","admin") //自定义claims存储数据
                    .claim("logo","logo.png");;
            System.out.println( builder.compact() );
        }
}

(2) 解析

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author: mayuhang  <br/>
 * Date: 2021/4/29:1:48  <br/>
 * Description:
 */
public class ParseJwtTest {
    public static void main(String[] args) {
        String token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiJBRE1JTiIsImlhdCI6MTYxOTYzMjg1NSwiZXhwIjoxNjE5NjMyOTE1LCJyb2xlcyI6ImFkbWluIiwibG9nbyI6ImxvZ28ucG5nIn0.D5SFUTBzCvGKp6MECT4-L3pIvU0Umnm__tm-zPSrf1U"; 
        Claims claims =
                Jwts.parser().setSigningKey("woniuxy").parseClaimsJws(token).getBody();
        System.out.println("id:"+claims.getId());
        System.out.println("subject:"+claims.getSubject());
        System.out.println("IssuedAt:"+claims.getIssuedAt());
        System.out.println("roles:"+claims.get("roles"));
        System.out.println("logo:"+claims.get("logo"));
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        System.out.println("签发时间:"+sdf.format(claims.getIssuedAt()));
        System.out.println("过期时间:"+sdf.format(claims.getExpiration()));
        System.out.println("当前时间:"+sdf.format(new Date()) );
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值