jwt相关问题及应用

本文介绍了JWT的出现原因、工作原理、JWT的结构和验证过程,并展示了JWT在SPA项目中的具体应用,包括JWTFilter和JwtUtils类的使用,用于身份验证和令牌管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

①、jwt出现的原因及工作原理

②、jwt工具类介绍,三种场景

③、jwt与vuex配合在SPA项目中的应用

1. JWT是什么

==========

JSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案

2. 为什么使用JWT

===============

JWT的精髓在于:“去中心化”,数据是保存在客户端的。

3. JWT的工作原理

===============

①. 是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户,示例如下:

{“UserName”: “Chongchong”,“Role”: “Admin”,“Expire”: “2018-08-08 20:15:56”}

②. 之后,当用户与服务器通信时,客户在请求中发回JSON对象

③. 为了防止用户篡改数据,服务器将在生成对象时添加签名,并对发回的数据进行验证

![](https://img-blog.csdnimg.cn/c51ad41cd12a46bdb321915c97e318be.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6IC 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 B5rGk5aeG55-l5LmO,size_20,color_FFFFFF,t_70,g_se,x_16)

4. JWT组成

===================================================================================================================================================================================================================

一个JWT实际上就是一个字符串,它由三部分组成:头部(Header)、载荷(Payload)与签名(signature)

JWT结构原理图:

JWT实际结构:eyJhbGciOiJIUzI1NiJ9.

eyJzdWIiOiJ7fSIsImlzcyI6InpraW5nIiwiZXhwIjoxNTYyODUwMjM3LCJpYXQiOjE1NjI4NDg0MzcsImp0aSI6ImM5OWEyMzRmMDc4NzQyZWE4YjlmYThlYmYzY2VhNjBlIiwidXNlcm5hbWUiOiJ6c3MifQ.

WUfqhFTeGzUZCpCfz5eeEpBXBZ8-lYg1htp-t7wD3I4

它是一个很长的字符串,中间用点(.)分隔成三个部分。

注意,JWT 内部是没有换行的,这里只是为了便于展示,将它写成了几行。

写成一行,就是下面的样子:Header.Payload.Signature

五,JWT的验证过程

==========

在验证一个JWT的时候,签名认证是每个实现库都会自动做的,但是payload的认证是由使用者来决定的。因为JWT里面可能会包含一个自定义claim,所以它不会自动去验证这些claim

它验证的方法其实很简单,只要把header做base64url解码,就能知道JWT用的什么算法做的签名,然后用这个算法,再次用同样的逻辑对header和payload做一次签名,并比较这个签名是否与JWT本身包含的第三个部分的串是否完全相同,只要不同,就可以认为这个JWT是一个被篡改过的串,自然就属于验证失败了。

接收方生成签名的时候必须使用跟JWT发送方相同的密钥

六,JWT在spa项目中的使用

================

项目中 JwtFilter 类

package com.zking.vue.util;

import java.io.IOException;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import io.jsonwebtoken.Claims;

/**

    • JWT验证过滤器,配置顺序 :CorsFilte–>JwtFilter–>struts2中央控制器
  • @author Administrator

*/

public class JwtFilter implements Filter {

// 排除的URL,一般为登陆的URL(请改成自己登陆的URL)

private static String EXCLUDE = “^/vue/userAction_login\.action?.*$”;

private static Pattern PATTERN = Pattern.compile(EXCLUDE);

private boolean OFF = false;// true关闭jwt令牌验证功能

@Override

public void init(FilterConfig filterConfig) throws ServletException {

}

@Override

public void destroy() {

}

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;

HttpServletResponse resp = (HttpServletResponse) response;

String path = req.getServletPath();

if (OFF || isExcludeUrl(path)) {// 登陆直接放行

chain.doFilter(request, response);

return;

}

// 从客户端请求头中获得令牌并验证

String jwt = req.getHeader(JwtUtils.JWT_HEADER_KEY);

Claims claims = this.validateJwtToken(jwt);

if (null == claims) {

// resp.setCharacterEncoding(“UTF-8”);

resp.sendError(403, “JWT令牌已过期或已失效”);

return;

} else {

String newJwt = JwtUtils.copyJwt(jwt, JwtUtils.JWT_WEB_TTL);

resp.setHeader(JwtUtils.JWT_HEADER_KEY, newJwt);

chain.doFilter(request, response);

}

}

/**

  • 验证jwt令牌,验证通过返回声明(包括公有和私有),返回null则表示验证失败

*/

private Claims validateJwtToken(String jwt) {

Claims claims = null;

try {

if (null != jwt) {

claims = JwtUtils.parseJwt(jwt);

}

} catch (Exception e) {

e.printStackTrace();

}

return claims;

}

/**

  • 是否为排除的URL

  • @param path

  • @return

*/

private boolean isExcludeUrl(String path) {

Matcher matcher = PATTERN.matcher(path);

return matcher.matches();

}

// public static void main(String[] args) {

// String path = “/sys/userAction_doLogin.action?username=zs&password=123”;

// Matcher matcher = PATTERN.matcher(path);

// boolean b = matcher.matches();

// System.out.println(b);

// }

}

JwtUtils 类

package com.zking.vue.util;

import java.util.Date;

import java.util.Map;

import java.util.UUID;

import javax.crypto.SecretKey;

import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

import io.jsonwebtoken.Claims;

import io.jsonwebtoken.JwtBuilder;

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

/**

  • JWT验证过滤器:配置顺序 CorsFilte->JwtUtilsr–>StrutsPrepareAndExecuteFilter

*/

public class JwtUtils {

/**

  • JWT_WEB_TTL:WEBAPP应用中token的有效时间,默认30分钟

*/

public static final long JWT_WEB_TTL = 30 * 60 * 1000;

/**

  • 将jwt令牌保存到header中的key

*/

public static final String JWT_HEADER_KEY = “jwt”;

// 指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。

private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;

private static final String JWT_SECRET = “f356cdce935c42328ad2001d7e9552a3”;// JWT密匙

private static final SecretKey JWT_KEY;// 使用JWT密匙生成的加密key

static {

byte[] encodedKey = Base64.decodeBase64(JWT_SECRET);

JWT_KEY = new SecretKeySpec(encodedKey, 0, encodedKey.length, “AES”);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值