JWT学习流程及使用

目录

一、简述

二、使用

三、jwt优点

四、jwt缺点

五、jwt与session对比

六、jwt组成结构

七、jwt工作流程

八、java使用jwt

九、HMAC SHA256 算法原理


一、简述

        JWT,即 JSON Web Token,定义了一种紧凑的、自包含的方式,用于在网络应用环境间以 JSON 对象安全地传输信息。

        JWT 是一个开放的行业标准 RFC 7519。JWT 传输的信息可以被验证和信任,因为它经过了数字签名。

        JWT 一般被用来在身份提供者和服务提供者间传递被认证用户的身份信息,以便于从资源服务器获取资源,也可以增加一些额外的业务逻辑所需的声明信息。

        JWT 常用于代替 Session,用于识别用户身份。传统上使用 Session 机制区别用户身份有两个缺点:一是占用服务器的存储资源,二是在集群部署下设计会非常复杂。JWT 完全可以解决 Session 方案存在的问题。

二、使用

        认证授权 (Authorization) :这是使用 JWT 的最常见场景。一旦用户登录,后续每个请求都将包含 JWT,允许用户访问该 Token 允许的路由、服务和资源。单点登录是现在广泛使用的 JWT 的一个特性,因为它的开销很小,而且可以轻松地跨域使用。

        信息交换 (Information Exchange) :对于安全的在各方之间传输信息而言,JSON Web Token 无疑是一种很好的方式。因为 JWT 可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

三、jwt优点

        跨语言:支持主流语言。

        自包含:包含必要的所有信息,如用户信息和签名等。

        易传递:很方便通过 HTTP 头部传递。

        JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。JWT 不加密的情况下,不能将秘密数据写入 JWT。

        JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。

四、jwt缺点

        由于服务器不保存 session 状态,因此 JWT 无法在使用过程中废止某个 token,或更改 token 的权限。一旦 JWT 签发,在到期之前就会始终有效,除非服务器部署额外的逻辑。

        JWT 本身包含认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

        为减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

五、jwt与session对比

        JWT 和 Session 相同点是,它们都是存储用户信息;然而,Session 是在服务器端的,而 JWT 是在客户端的。Session 方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。而 JWT 方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。Session 的状态是存储在服务器端,客户端只有 session id;而 Token 的状态是存储在客户端。

六、jwt组成结构

        JWT 的 token 由三段小数点分隔组成的字符串:header.payload.signature。

1. JWT header
头部包含两部分:声明类型和使用的哈希算法,通常直接使用HMAC SHA256,就是HS256。
{
    "typ": "JWT",
    "alg": "HS256"
}
将头部进行 Base64 编码构成第一部分。Base64 是一种用 64 个字符来表示任意二进制数据的方法,常用于在 URL、Cookie、网页中传输少量二进制数据。

2. JWT payload
也称为JWT claims,放置需要传输的信息,有三类:
保留claims,主要包括iss发行者、exp过期时间、sub主题、aud用户等。
公共claims,定义新创的信息,比如用户信息和其他重要信息。
私有claims,用于发布者和消费者都同意以私有的方式使用的信息。
JWT规定7个官方字段,供选用:
iss (issuer):签发人。
exp (expiration time):过期时间。
sub (subject):主题。
aud (audience):受众。
nbf (Not Before):生效时间。
iat (Issued At):签发时间。
jti (JWT ID):编号。
支持定义私有字段,示例:
{
    "iss": "jwt.io",
    "exp": 1496199995458,
    "name": "sinwaj",
    "role": "admin"," 
}
JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分

3. JWT signature 生成签名部分,需要准备:编码的 header、编码的 payload 和一个秘钥,签名算法是 header 指定的算法,然对这些数据进行签名。 
签名公式如下:HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 
其中:secret 为加密使用的盐,也可以认为是私钥,千万不能泄露。secret 保存在服务器端,JWT 的生成也在服务器端,secret 用来进行 jwt 的签发和 jwt 的验证,它就是服务端的私钥。所以,在任何场景下都不应该泄露出去。一旦客户端得知这个 secret,那就意味着客户端是可以自我签发 jwt。

七、jwt工作流程

  • 用户携带用户名和密码请求访问;
  • 服务器校验用户凭据;
  • 应用提供一个 token 给客户端;
  • 客户端存储 token,并且在随后的每一次请求中都带着它;
  • 服务器校验 token 并返回数据。

        需要注意问题:

  • 每一次请求都需要 token;
  • Token 应该放在请求 header 中;
  • 需要将服务器设置为接受来自所有域的请求,用 Access-Control-Allow-Origin: *。

八、java使用jwt

        1、引入依赖

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.3.0</version>
        </dependency>

        2、编写jwt工具类

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import java.util.Calendar;
import java.util.Map;

public class JwtUtil {

    // 签名密钥
    private static final String SECRET = "jsdhksuis&*^8";

    /**
     * 生成token
     * @param payload token携带的信息
     * @return token字符串
     */
    public static String generateToken(Map<String,String> payload){
        // 指定token过期时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR, 24);  // 24小时
        JWTCreator.Builder builder = JWT.create();
        // 构建payload
        payload.forEach(builder::withClaim);
        // 指定过期时间和签名算法,并返回token
        String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SECRET));
        return token;
    }

    /**
     * 解析token
     * @param token token字符串
     * @return 解析后的token类
     */
    public static DecodedJWT decodeToken(String token){

        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT decodedJWT = jwtVerifier.verify(token);
        return decodedJWT;
    }
}

        3、测试

@SpringBootApplication
public class AuthorizationApp {

    public static void main(String[] args) {

        SpringApplication.run(AuthorizationApp.class,args);

        Map<String, String> payload = new HashMap<>();
        payload.put("userId", "9999");
        payload.put("userName", "wgh");
        String token = JwtUtil.generateToken(payload);
        System.out.println("token: " + token);

        // 解析令牌并获取用户信息 ------------------------------------------------
        try {
            DecodedJWT decodedJWT = JwtUtil.decodeToken(token);
            String userId = decodedJWT.getClaim("userId").asString();
            String userName = decodedJWT.getClaim("userName").asString();
            String exp = decodedJWT.getExpiresAt().toString();
            System.out.println("userId: " + userId);
            System.out.println("userName: " + userName);
            System.out.println("exp: " + exp);
        } catch (JWTDecodeException e) {
            System.out.println("令牌错误");
        } catch (TokenExpiredException e) {
            System.out.println("令牌过期");
        }
    }

}

        4、结果

九、HMAC SHA256 算法原理

  • 1.输入密钥key和固定的数据(0x36)进行异或操作生成一个64B的数据kx;
  • 2.使用kx+输入数据执行sha256算法得到32B的out;
  • 3.使用密钥key和固定的数据(0x5C)进行异或操作生成一个64B的数据kx';
  • 4.使用kx'+第2步生成的out执行sha256算法得到32B的out,此结果就是HMACSHA256算法输出。

综述:HMAC加密算法是一种基于数据摘要算法和共享密钥的消息认证协议.它可以有效地防止数据在传输过程中被篡改,维护了数据的完整性、可靠性和安全性。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值