拦截器和jwt的联合使用

(一)

在config层设置所要拦截的页面 LoginConfig
package com.bim.bimbookshop.config;
​
import com.bim.bimbookshop.interceptor.LoginInterceptor;
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;
​
/**
 * 登录拦截配置类
 */
@Configuration   //表明这个是配置类
public class LoginConfig implements WebMvcConfigurer {
​
    @Autowired
    private LoginInterceptor loginInterceptor;
​
    /**
     * 有没有这个login都打不开
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)//添加拦截器
                 .addPathPatterns("/**")  //配置拦截路径
                 .excludePathPatterns("/login/**","/static/**","/templates/**");//配置排除路径
    }
}
注意:上面的"/login/**"表示/login下的所有路径,所有如果登录页面路径为时,就要额外添加"/"
eg:.excludePathPatterns(  // 配置排除路径,以下请求不会被拦截
                        "/login",          // 登录页面
                        "/login/**",       // 登录相关的请求,如登录表单提交
                        "/register",       // 注册页面
                        "/register/**",    // 注册相关的请求
                        "/static/**",      // 静态资源,如CSS、JS、图片等
                        "/css/**",         // CSS文件
                        "/js/**",          // JavaScript文件
                        "/images/**",      // 图片文件
                        "/favicon.ico",    // 网站图标
                        "/error"           // 错误页面
                )
在interceptor 或 handle 层配置拦截器实现类 LoginInterceptor
package com.bim.bimbookshop.interceptor;
​
import com.bim.bimbookshop.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
​
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​
/**
 * 拦截器
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {
​
    /**
     * 除了登录请求以外的其他请求都要进行过滤
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Cookie[] cookies = request.getCookies();
        if(cookies != null){
            for (Cookie cookie:cookies){
                if("token".equals(cookie.getName())){
                    String userToken = cookie.getValue();
                    if(!StringUtils.hasText(userToken)){
                        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                    }
                    //解析token看看是否成功
                    try {
                        Claims claims = JwtUtil.parseJWT(userToken);
                        claims.getSubject();
                    }catch (Exception e){
                        //e.printStackTrace();
                        System.out.println("token信息出错");
                        return false;
                    }
                    return true;  //放行
                }
            }
        }
        return false;
    }
}
在util层创建JWT实现类 JwtUtil
package com.qcby.springboot.util;
​
/**
 * JWT工具类
 */
​
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
​
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;
​
public class JwtUtil {
    //有效期为
    public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 * 1000
    //设置秘钥明文
    public static final String JWT_KEY = "qcby";
​
    /**
     * 创建token
     * @param subject
     * @return
     */
    public static String createJWT(String subject) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
​
        long expMillis = nowMillis + JwtUtil.JWT_TTL;
        Date expDate = new Date(expMillis);
        SecretKey secretKey = generalKey();
​
        JwtBuilder builder = Jwts.builder()
                .setId(UUID.randomUUID().toString())              //唯一的ID
                .setSubject(subject)   // 主题  可以是JSON数据
                .setIssuer("wd")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(expDate);// 设置过期时间
        return builder.compact();
    }
​
    /**
     * 生成加密后的秘钥 secretKey
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }
​
    /**
     * 解析
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }
​
    public static void main(String[] args) {
        String token = JwtUtil.createJWT("qd");
        System.out.println(token);
    }
​
}
加入JWT依赖
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

最后在登录成功后根据用户ID创建token
public ResponseResult Login(Login login,HttpServletResponse response){
    。。。
    。。。
    。。。
    //创建token
    String token = this.jwtUtil.createJWT(String.valueOf(user.getUserId()));
    //将token信息设置如cookie当中,并且将cookie传到http
    Cookie cookie = new Cookie("token",token);
    cookie.setPath("/");   //代表cookie的值将会被发送到服务器上的所有路径
    cookie.setMaxAge(36000); //设置cookie的过期时间
    response.addCookie(cookie);//将Cookie添加到响应中
    。。。
    return;
}

注意:在拦截器实现类 LoginInterceptor 中会拿到存在cookie中的token的值

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

(二)

加入JWT依赖
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
配置JWT环境
spring:
    。。。
    。。。
jwt:
  secret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4K67DMlSPXbgG0MPp0gH
  expire: 86400000
  #  expire: 10000
  subject: door
在util层创建JWT实现类 JwtUtil
package com.southwind.util;
​
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
​
import java.util.Date;
import java.util.UUID;
​
@ConfigurationProperties(prefix = "jwt")
@Component
public class JwtUtil {
    private long expire;
    private String secret;
    private String subject;
​
    /**
     * 生成token
     *
     * @param userId
     * @return
     */
    public String createToken(String userId) {
        String token = Jwts.builder()
                //载荷:自定义信息
                .claim("userId", userId)
                //载荷:默认信息
                .setSubject(subject) //令牌主题
                .setExpiration(new Date(System.currentTimeMillis() + expire)) //过期时间
                .setId(UUID.randomUUID().toString())
                //签名哈希
                .signWith(SignatureAlgorithm.HS256, secret)
                //组装jwt字符串
                .compact();
        return token;
    }
​
    public boolean checkToken(String token){
        if(StringUtils.isEmpty(token)){
            return false;
        }
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
​
    public long getExpire() {
        return expire;
    }
​
    public void setExpire(long expire) {
        this.expire = expire;
    }
​
    public String getSecret() {
        return secret;
    }
​
    public void setSecret(String secret) {
        this.secret = secret;
    }
​
    public String getSubject() {
        return subject;
    }
​
    public void setSubject(String subject) {
        this.subject = subject;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值