基于JWT的Token简介

TOKEN简介

在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思,一般作为邀请、登录系统使用。Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位

为什么要使用TOKEN

  1. 为权限控制作接口 ,后端HTTP接口要为前端项目提供服务,为了接口不被随意调用就需要权限验证,而token就是验证的重要方法;
  2. 防止CSRF攻击 ,CSRF攻击是常见且危害巨大的攻击手段,Token在一定程度上可以防御这种攻击;
  3. 利用Token为第三方提供服务 Token中可以为第三方提供权限,而非账号密码,提高了安全性;
  4. Token是无状态的 与session不同的是,token可以在多个服务中共享,即使在部署在不同的服务器上;

Jwt Token结构

  1. Header Header通常由两部分组成:令牌的类型,即JWT。和常用的散列算法,如HMAC SHA256或RSA。

{
“typ”: “JWT”,
“alg”: “HS256”
}
由上可知,该token使用HS256加密算法,将头部使用Base64编码可得到如下个格式的字符串:
eyJhbGciOiJIUzI1NiJ91

  1. Playload 包括三种声明模式。
  • Registered claims(注册声明): 这些是一组预先定义的声明,它们不是强制性的,但推荐使用,以提供一组有用的,可互操作的声明。 其中一些是:iss(发行者),exp(到期时间),sub(主题),aud(受众)等
  • Public claims (公开声明): 这些可以由使用JWT的人员随意定义。 但为避免冲突,应在IANA JSON Web令牌注册表中定义它们,或将其定义为包含防冲突命名空间的URI。
  • Private claims(私有声明): 这些是为了同意使用它们但是既没有登记,也没有公开声明的各方之间共享信息,而创建的定制声明。
  • Playload 结构如下:

{
“iss”: “Online JWT Builder”,
“iat”: 1416797419,
“exp”: 1448333419,
…….
“userid”:10001
}
有效载荷中存放了token的签发者(iss)、签发时间(iat)、过期时间(exp)等以及一些我们需要写进token中的信息。有效载荷也使用Base64编码得到如下格式的字符串:
eyJ1c2VyaWQiOjB91

  1. Signature 签名
  • 签名就是把上面两部分进行结合,再加上一些本地信息进行拼接,然后使用头部里面指定的算法进行生成对应的一串字符

例如头部与载体加密拼接后的字符串为eyJhbGciOiJIUzI1NiJ91.eyJ1c2VyaWQiOjB91再次利用加密算法(HS256)与自定义的密钥(secret)加密得到签名部分字符串:rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

  1. Jwt生成的Token格式

将上面三个方法生成的字符串再次拼接就得到了完整的Token:
eyJhbGciOiJIUzI1NiJ91.eyJ1c2VyaWQiOjB91.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

如何使用Token

  1. 后端生成并返回: 在身份验证中,当用户使用他们的凭证成功登录时,JSON Web Token将被返回并且必须保存在本地(通常在本地存储中,但也可以使用Cookie),而不是在传统方法中创建会话 服务器并返回一个cookie
  2. 访问请求验证Token: 前端拿到后端返回的Token时,在后续请求中都需要加上Token(如果后端鉴权有使用到Token的话)。一般情况下后端鉴权会判断这几种条件,请求是否携带Token,该Token是否过期,Token中携带的权限是否符合(权限信息一般是放置到PlayLoad中)。

PlayLoad数值如何设置

  1. 过期时间设置: 前面说到鉴权会判定Token是否过期,而过期时间是默认设置在PlayLoad中。一般情况下过期时间不能设置的太短,想象下用户登录十分钟后Token就过期了,那他就需要重新请求Token才能继续用,就像你的手机每过十秒钟就会锁屏,这时就需要了解Refresh Token,限于篇幅可以在这篇博客了解。
  2. 隐私信息: 虽然Token信息通常都是加密的,但是被别人获取到仍有可能读取到包含的信息,因此绝对不能将隐私信息存放在Token里。而默认是采用Base64编码的,连加密都算不上,这样就更不安全了。

如何实现基础的Token生成与解析

Token生成

// 生成成token
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import io.jsonwebtoken.*;
import java.util.Date;    
 
//Sample method to construct a JWT
private String createJWT(String id, String issuer, String subject, long ttlMillis) {
//The JWT signature algorithm we will be using to sign the token
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//We will sign our JWT with our ApiKey secret
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(apiKey.getSecret());
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//Let's set the JWT Claims
JwtBuilder builder = Jwts.builder().setId(id)
                                .setIssuedAt(now)
                                .setSubject(subject)
                                .setIssuer(issuer)
                                .signWith(signatureAlgorithm, signingKey);
 
//if it has been specified, let's add the expiration
if (ttlMillis >= 0) {
    long expMillis = nowMillis + ttlMillis;
    Date exp = new Date(expMillis);
    builder.setExpiration(exp);
}
//Builds the JWT and serializes it to a compact, URL-safe string
return builder.compact();
}

Token解析

// 生成成token
import javax.xml.bind.DatatypeConverter;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Claims;
 
//Sample method to validate and read the JWT
private void parseJWT(String jwt) {
//This line will throw an exception if it is not a signed JWS (as expected)
Claims claims = Jwts.parser()        
   .setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret()))
   .parseClaimsJws(jwt).getBody();
System.out.println("ID: " + claims.getId());
System.out.println("Subject: " + claims.getSubject());
System.out.println("Issuer: " + claims.getIssuer());
System.out.println("Expiration: " + claims.getExpiration());
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值