基于JWT令牌和拦截器实现登录校验

基于JWT令牌和拦截器实现登录校验



前言

提示:这里可以添加本文要记录的大概内容:

浏览器发出未经服务器校验的请求,访问者可以随意访问更改数据库的内容,很不安全,所以用拦截器和jwt令牌完成浏览器请求的校验


提示:以下是本篇文章正文内容,下面案例可供参考

一、jwt令牌

1.jwt令牌的组成

在这里插入图片描述

2.使用场景

在这里插入图片描述

二、使用步骤

1.导入依赖

            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>

2.jwt工具类-JwtUtil 生成并解析jwt

作用:用于生成、解析jwt令牌

方法:

  1. public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims)
    用于生成jwt令牌
  2. public static Claims parseJWT(String secretKey, String token)
    用于解析jwt令牌
package com.sky.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

public class JwtUtil {
    /**
     * 生成jwt
     * 使用Hs256算法, 私匙使用固定秘钥
     *
     * @param secretKey jwt秘钥
     * @param ttlMillis jwt过期时间(毫秒)
     * @param claims    设置的信息
     * @return
     */
    public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // 指定签名的时候使用的签名算法,也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);

        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
                .setClaims(claims)
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
                // 设置过期时间
                .setExpiration(exp);

        return builder.compact();
    }

    /**
     * Token解密
     *
     * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
     * @param token     加密后的token
     * @return
     */
    public static Claims parseJWT(String secretKey, String token) {
        // 得到DefaultJwtParser
        Claims claims = Jwts.parser()
                // 设置签名的秘钥
                .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
                // 设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }

}

三、拦截器

作用:拦截来自浏览器的请求,在指定的方法调用前后,根据业务需要执行预先设定的代码

在这里插入图片描述
在这里插入图片描述

代码实现:

package com.sky.config;

import com.sky.interceptor.JwtTokenAdminInterceptor;
import com.sky.interceptor.JwtTokenUserInterceptor;
import com.sky.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.List;

/**
 * 配置类,注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
    @Autowired
    private JwtTokenUserInterceptor jwtTokenUserInterceptor;

    /**
     * 注册自定义拦截器
     * @param registry
     */
    protected void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenAdminInterceptor)
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/employee/login");

        registry.addInterceptor(jwtTokenUserInterceptor)
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/user/login")
                .excludePathPatterns("/user/shop/status");
    }
   }

总结

通过拦截器拦截来自浏览器的请求,只有携带jwt令牌的请求才能访问服务端

  • 36
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JWT(JSON Web Token)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为 JSON 对象安全地传输信息。一般来说,JWT 用于认证和授权,其主要应用场景为 API 接口鉴权。生成 JWT 的流程可以通过拦截器实现,以下是一个简单的生成 JWT 令牌拦截器实现过程: 1. 创建一个 JWT 工具类,用于生成和解析 JWT 令牌。 2. 创建一个 JWT 拦截器类,该类需要实现 HandlerInterceptor 接口。 3. 在 preHandle 方法中,判断当前请求是否需要生成 JWT 令牌,如果需要,则使用 JWT 工具类生成令牌,并将其存储在请求头中。 4. 在 postHandle 方法中,将生成的 JWT 令牌返回给客户端。 5. 在 afterCompletion 方法中,清除请求头中的 JWT 令牌。 以下是一个简单的生成 JWT 令牌拦截器示例: ``` public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 判断当前请求是否需要生成 JWT 令牌 if (request.getRequestURI().startsWith("/api/")) { // 获取用户信息 User user = (User) request.getSession().getAttribute("user"); // 判断用户信息是否为空 if (user != null) { // 使用 JWT 工具类生成令牌 String token = JwtUtils.generateToken(user); // 将生成的 JWT 令牌存储在请求头中 response.setHeader("Authorization", token); } else { // 用户信息为空,返回未授权状态码 response.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 将生成的 JWT 令牌返回给客户端 response.setHeader("Authorization", response.getHeader("Authorization")); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 清除请求头中的 JWT 令牌 response.setHeader("Authorization", null); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值