JWT 登录认证 Springboot

SystemPara.SECRET 是自己定义的常量

依赖

        <!-- token -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.3.0</version>
        </dependency>

一、JWT工具类

package com.cn.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.cn.util.SystemPara;
import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;

import java.io.UnsupportedEncodingException;
import java.security.SignatureException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
  * @Author 徐本锡
  * @Date 2019/7/4
  * @Param
  * @return
  **/
public class JWTUtil {

    private static final long EXPIRE_TIME = 5 * 60 * 1000;

    public static final String TOKEN_HEADER = "token";
    public static final String TOKEN_PREFIX = "xbx_";

    /**
      * @Author 徐本锡
      * @Description 生成token
      * @Date 2019/7/4  
      * @Param 
      * @return 
      **/
    public static  String  createToken (String logon_name) throws UnsupportedEncodingException {

        //签名发布时间
        Date createTime = new Date();

        //设置签名过期时间  5分钟
        Calendar nowTime=Calendar.getInstance();
        nowTime.add(Calendar.MINUTE,5);
        Date expiresTime = nowTime.getTime();
        //Date expiresTime = new Date(System.currentTimeMillis() + EXPIRE_TIME);

        Map<String,Object> map=new HashMap<String, Object>();
        map.put("alg","HS256");//设置算法 为HS256
        map.put("typ","JWT");//设置类型为JWT

        String token= JWT.create()
                .withHeader(map)
                .withClaim("logon_name",logon_name) //可以将基本不重要的对象信息放到claims中
                .withIssuedAt(createTime)//设置签发时间
                .withExpiresAt(expiresTime)//设置过去时间 过期时间大于签发时间
                .sign(Algorithm.HMAC256(SystemPara.SECRET));//用公共密钥加密

        return token;

    }

    /**
     * 校验token是否正确
     *
     * @param token  密钥
     * @param secret 用户的密码
     * @return 是否正确
     */
    public static boolean verify(String token, String logon_name, String secret) {
        try {
            //根据密码生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(SystemPara.SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("logon_name", logon_name)
                    .build();
            //效验TOKEN
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getLogonName(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("logon_name").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

}

二、登录时生成token

service方法中生成token,然后放入返回结果

  //service方法中生成token,然后放入返回结果
  String token = JWTUtil.createToken(loginName);
  resultMap.put("token", token);

controller中  把token放入 response响应中

package com.cn.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cn.domain.EmpinforVo;
import com.cn.service.LogonService;
import com.cn.util.JWTUtil;
import com.cn.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xbx
 * @date 2019-05-13
 */
@RestController
@RequestMapping("/Logon")
public class LogonController {
    private final LogonService logonService;

    @Autowired
    public LogonController(LogonService logonService) {
        this.logonService = logonService;
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    public R logon(HttpServletResponse response, EmpinforVo entity) throws Exception{
        Map resultMap = logonService.logon(entity);
        String token = (String) resultMap.get("token");

        //放到响应头部
        response.setHeader(JWTUtil.TOKEN_HEADER, JWTUtil.TOKEN_PREFIX + token);

        return R.success(resultMap);
    }

}

三、创建拦截器

package com.cn.interceptor;

import com.cn.util.JWTUtil;
import com.cn.util.SystemPara;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * token验证拦截
 */
public class JwtInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        // 取得token
        String tokenHeader = request.getHeader(JWTUtil.TOKEN_HEADER);
        if (tokenHeader == null || "".equals(tokenHeader)) {
            throw new Exception("token不存在");
        }
        if (!tokenHeader.startsWith(JWTUtil.TOKEN_PREFIX)) {
            throw new Exception("这是你自己造的token吧");
        }
        String token = tokenHeader.replace(JWTUtil.TOKEN_PREFIX, "");//真正的token

        String logonName = JWTUtil.getLogonName(token);

        // 验证token是否有效
        if (!JWTUtil.verify(token, logonName, SystemPara.SECRET)){
            throw new Exception("token已失效");
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub

    }

}

 四、配置拦截器

package com.cn.config;

import com.cn.interceptor.JwtInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


/**
  * @Author 徐本锡
  **/
@Configuration
public class WebAppConfiguration implements WebMvcConfigurer  {

    /**
     * 配置静态资源
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        String path= "/";
        for(int i=1900; i<=2500; i++){
            path = String.valueOf(i);
            registry.addResourceHandler("/"+path+"/**").addResourceLocations("file:C:/"+path+"/");
            registry.addResourceHandler("/"+path+"/**").addResourceLocations("file:/"+path+"/");
        }
    }

    /**
     * 跨域支持
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
                .maxAge(3600 * 24);
    }

    /**
     * 添加拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截路径可自行配置多个 可用 ,分隔开
        registry.addInterceptor(new JwtInterceptor()).addPathPatterns("/**").excludePathPatterns("/Logon");
    }


}   

猜你喜欢

转载自blog.csdn.net/xubenxismile/article/details/94623594