文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringBoot-JWT生成Token和拦截器的使用(访问受限资源)

2024-04-02 19:55

关注

1.什么是JWT

JWT官方的定义是:JSON Web令牌(JWT)是一个开放标准(RFC 7519),用于作为JSON对象在各方之间安全地传输信息。 可以验证和信任该信息,因为它是数字签名的。 jwt可以使用一个秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

其实他本质上就是一个签名,用于验证用户是否可以请求受限资源(例如在商城中向服务器请求个人中心页面信息、购物车页面信息)

比如说现在在你家楼下有一家有一家自助餐厅,自助餐厅的门前有一个收银柜台。到了中午你感觉到肚子饿了,去了自助餐厅吃饭,去收银柜台交了钱,收银柜台给你开了一张你交过钱的证明,该证明里写了你什么时候交的钱,交了多少钱等信息,现在你拿着这张证明去餐厅里面吃饭,吃饭时候只要给这张证明就行,因为他认证了你的信息,店员知道你交过钱了也不会让你再交一次,同时防止了你不交钱吃饭的情况。

在这个例子中,我们如果把场景转换到网上商城(前后端分离的情况),收银柜台就是登录,登录完后服务器给你一个证明,证明你登录过了,这个证明有生成的时间、你的信息等等,这时候你想访问购物车,就拿着这个证明发给服务器,服务器验证该证明,验证通过后返回给你想要的数据。

还有一种情况就是如果你没有登录,想直接访问购物车的数据,服务器会发现你没有token(或者你伪造了一个token服务器验证不通过或者token过期),就会让你重新登录,从而实现了拦截访问受限资源的功能。

2.JWT生成token

2.1 添加依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

2.2 生成token

该案例为 在 登录的Controller中,用户的账号密码输入正确,生成token,其中最重要的是token的密码,验证token时候需要使用

JwtBuilder builder = Jwts.builder();
String token = builder.setSubject("userName")
        .setIssuedAt(new Date()) //设置token生成时间
        .setId(u.getUserId() + "")//设置tokenID
        .setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000))//设置过期时间,现在为设置 一天
        .signWith(SignatureAlgorithm.HS256, "123456")//设置token密码,解析token需要使用
        .compact();

到此token生成完毕,接着返回给前端,前端收到后将其存在cookie当中 这里提供一个设置cookie的工具类代码,设置或者取出cookie可以直接使用 每次前端发送请求时候都在 请求头 中携带token即可

var operator = "=";

//取出cookie
function getCookieValue(keyStr){
	var value = null;
	var s = window.document.cookie;
	var arr = s.split("; ");
	for(var i=0; i<arr.length; i++){
		var str = arr[i];
		var k = str.split(operator)[0];
		var v = str.split(operator)[1];
		if(k == keyStr){
			value = v;
			break;
		}
	}
	return value;
}
//设置cookie
function setCookieValue(key,value){
	document.cookie = key+operator+value;
}

2.3 使用拦截器解析token

配置拦截器

其中ResultVO和ResStatus为封装的返回对象,代码如下:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultVO {
    @ApiModelProperty("响应状态码")
    private Integer code;
    @ApiModelProperty("响应信息")
    private String msg;
    @ApiModelProperty("响应数据")
    private Object Data;
}
public class ResStatus {
    public static Integer OK = 10000;
    public static Integer NO = 10001;
    public static Integer PASS = 20002;
}
@Component
public class CheckTokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //因为是在请求头中发送token,所以第一次请求的方法为"OPTIONS",具体可以看TCP/IP协议
        String method = request.getMethod();
        if("OPTIONS".equalsIgnoreCase(method)){
            return true;
        }
        String token = request.getHeader("token");
        System.out.println("token:"+token);
        if(token == null){
            ResultVO resultVO = new ResultVO(ResStatus.NO,"请先登录",null);
            doResponse(response,resultVO);
        }else{
            try{
                //在jwt中,只要token不合法或者验证不通过就会抛出异常
                JwtParser parser = Jwts.parser();
                parser.setSigningKey("123456");
                Jws<Claims> claimsJws = parser.parseClaimsJws(token);
                return true;
            }catch (ExpiredJwtException e1) {
                ResultVO resultVO = new ResultVO(ResStatus.PASS, "登录过期,请重新登录", null);
                doResponse(response,resultVO);
            }catch (UnsupportedJwtException e2){
                ResultVO resultVO = new ResultVO(ResStatus.NO, "Token不合法,已记录恶意IP", null);
                doResponse(response,resultVO);
            }catch (Exception e3){
                ResultVO resultVO = new ResultVO(ResStatus.NO, "请先登录", null);
                doResponse(response,resultVO);
            }
        }
        return false;
    }

    @SneakyThrows
    private void doResponse(HttpServletResponse response, ResultVO resultVO) {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        String s = new ObjectMapper().writeValueAsString(resultVO);
        out.print(s);
        out.flush();
        out.close();
    }
}

设置拦截器拦截的内容

拦截了shopcart的请求,排除了user开头的请求,因为user开头请求负责登录和注册不应被拦截

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Resource
    private CheckTokenInterceptor checkTokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(checkTokenInterceptor)
                .addPathPatterns("/shopcart/**")
                .excludePathPatterns("/user/**");
    }
}

到此这篇关于SpringBoot-JWT生成Token和拦截器的使用(访问受限资源)的文章就介绍到这了,更多相关SpringBoot-JWT生成Token和拦截器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯