返回顶部
首页 > 资讯 > 后端开发 > Python >SpringBoot-JWT生成Token和拦截器的使用(访问受限资源)
  • 102
分享到

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

2024-04-02 19:04:59 102人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录1.什么是Jwt2.JWT生成token2.1 添加依赖2.2 生成token2.3 使用拦截器解析token1.什么是JWT JWT官方的定义是:JSON WEB令牌(JWT)

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和拦截器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

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

本文链接: https://lsjlt.com/news/148251.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作