您的位置 首页 java

springboot集成JWT实现token授权

引入JWT相关依赖

  <!--引入jwt依赖-->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.5.0</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.7.0</version>
</dependency>  

编写JWT工具类

 package com.democxy.common.utils;

import io.jsonwebtoken.*;
import java.util.Date;
​
/**
 * @author SHILING_DENG
 * @version 2020-05-05
 *
 */public class JwtUtil {
​
​
    //设置过期时间为15分钟
    public static final long EXPIRE_TIME = 15*60*1000;
​
    /**
     * token私钥
     */    private static final String TOKEN_SECRET = "6CvvNscuUDAq*JxE";
​
    /**
     * 签发JWT
     * @param id 可以设置为登录账户的ID
     * @param subject 可以是JSON数据,如登录用户的JSON字符串 尽可能少
     * @param ttlMillis token有效时间
     * @return
     */    public static String signToken(String id, String subject, long ttlMillis) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setSubject(subject)   // 主题
                .setIssuer("admin")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(SignatureAlgorithm.HS256, TOKEN_SECRET); // 签名算法以及密匙
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }
​
    /**
     * 验证JWT
     * @param token
     * @return
     */    public static boolean validateToken(String token) {
        try {
            Claims claims = parseToken(token);
            if (claims!=null){
                return true;
            }else{
                return false;
            }
​
        } catch (ExpiredJwt Exception  e) {
           return false;
        } catch (SignatureException e) {
            return false;
        } catch (Exception e) {
            return false;
        }
    }
​
​
​
    /**
     * 解析JWT字符串
     * @param token
     * @return
     * @throws Exception
     */    public static Claims parseToken(String token){
        Claims body = null;
        try {
            body = Jwts.parser()
                    .setSigningKey(TOKEN_SECRET)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            e.printStackTrace();
        } catch (UnsupportedJwtException e) {
            e.printStackTrace();
        } catch (MalformedJwtException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        return body;
    }
​
    public static void main(String[] args){
//        String token = signToken("1", "admin", EXPIRE_TIME);
//        System.out.println(token);
//        System.out.println(validateToken(token));
    }
}
​  

编写全局异常处理相关类

 package com.democxy.common.exception;
​
/**
 * 自定义异常类
 * @author shiling
 * @version 2020-04-28
 */public class CustomException extends RuntimeException {
​
    private int code;
    private String  msg ;
​
    public int getCode() {
        return code;
    }
​
    public String getMsg() {
        return msg;
    }
​
    public CustomException() {
        this(1001, "接口错误");
    }
​
    public CustomException(String msg) {
        this(1001, msg);
    }
​
    public CustomException(int code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }
​
}
​  

 package com.democxy.common.global;
​
/**
 * 响应数据
 */public class ResponeData<T> {
​
    private int code;
​
    private String msg;
​
    private T data;
​
    public int getCode() {
        return code;
    }
​
    public void setCode(int code) {
        this.code = code;
    }
​
    public String getMsg() {
        return msg;
    }
​
    public void setMsg(String msg) {
        this.msg = msg;
    }
​
    public T getData() {
        return data;
    }
​
    public void setData(T data) {
        this.data = data;
    }
​
    public ResponeData(T data) {
        this(ResultCode.SUCCESS,data);
    }
​
    public ResponeData(ResultCode resultCode, T data) {
        this.code = resultCode.getCode();
        this.msg = resultCode.getMsg();
        this.data = data;
    }
}  
 package com.democxy.common.global;
​
/**
 * 响应枚举类
 * @author shiling
 * @version 2020-04-28
 */public enum ResultCode {
​
    VALIDATE_ FAILED (1002, "参数校验失败"),
​
    SUCCESS(200, "操作成功"),
​
    FAILED(500, "响应失败"),
​
    NOT_FOUND(404, "未知请求"),
​
    LOGIN_FAILED(4040, "登录失败!");
​
    private int code;
    private String msg;
​
    public int getCode() {
        return code;
    }
​
    public String getMsg() {
        return msg;
    }
​
    ResultCode(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
​
​
}  
 package com.democxy.common.exception;
​
import com.democxy.common.global.ResponeData;
import com.democxy.common.global.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
​
/**
 * 全局异常处理类 加上@ControllerAdvice注解或者@RestControllerAdvice,
 * 加@RestControllerAdvice只能全局处理RestFul接口异常
 * @author shiling
 * @version 2020-04-28
 */@RestControllerAdvice
public class ExceptionControllerAdvice {
​
    Logger logger = LoggerFactory.getLogger(ExceptionControllerAdvice.class);
​
    /**
     * 表单验证异常处理
     * @param e
     * @return
     */    @ExceptionHandler(BindException.class)
    public ResponeData<String> BindExceptionHandler(BindException e) {
        ObjectError objectError = e.getAllErrors().get(0);
        // 注意哦,这里传递的响应码枚举
        logger.error("表单数据校验异常",e);
        return new ResponeData<>(ResultCode.VALIDATE_FAILED, objectError.getDefaultMessage());
    }
​
    /**
     * 自定义异常处理
     * @param e
     * @return
     */    @ExceptionHandler(CustomException.class)
    public ResponeData<String> CustomExceptionHandler(CustomException e) {
        logger.error("自定义异常",e);
        // 注意哦,这里传递的响应码枚举
        if (4040 == e.getCode()){
            return new ResponeData<>(ResultCode.LOGIN_FAILED, e.getMsg());
        }else {
            return new ResponeData<>(ResultCode.FAILED, e.getMsg());
        }
    }
​
    /**
     * Exception异常处理
     * @param e
     * @return
     */    @ExceptionHandler(Exception.class)
    public ResponeData<String> ExceptionHandler(Exception e) {
        //记录日志信息
        logger.error("服务异常",e);
        // 注意哦,这里传递的响应码枚举
        return new ResponeData<>(ResultCode.FAILED, "服务异常!");
    }
​
​
}  

编写登录拦截器

 package com.democxy.common.interceptor;
​
import com.democxy.common.exception.CustomException;
import com.democxy.common.utils.JwtUtil;
import org.springframework.web. servlet .HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​
/**
 * 授权验证拦截器
 */public class AuthenticationInterceptor implements HandlerInterceptor {
​
    @ Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从 http 请求头中取出 token
        String token = request.getHeader("token");
        System.out.println(token);
        boolean verity = JwtUtil.validateToken(token);
        if (!verity){
            throw new CustomException(4040,"token过期,请重新登录");
        }
        return true;
    }
​
​
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
​
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}
​  

注册拦截器

 package com.democxy.common. config ;
​
import com.democxy.common.interceptor.AuthenticationInterceptor;
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 WebConfig implements WebMvcConfigurer {
​
    // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthenticationInterceptor())
                .addPathPatterns("/","/admin/**")
                .excludePathPatterns("/admin/account/login","/admin/account/logout");
    }
​
}  

文章来源:智云一二三科技

文章标题:springboot集成JWT实现token授权

文章地址:https://www.zhihuclub.com/192392.shtml

关于作者: 智云科技

热门文章

网站地图