zoukankan      html  css  js  c++  java
  • java之JWT认证、JWT拦截器、JWT工具类、日期工具类

    1、依赖

    <dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.1</version>
    </dependency>
    

    2、JWT工具类

    package com.jay.SpringBootStudy8.utils;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTCreator;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.interfaces.DecodedJWT;
    
    import java.time.LocalDateTime;
    import java.time.temporal.ChronoUnit;
    import java.util.Date;
    import java.util.HashMap;
    
    /**
     * Jwt工具类
     */
    public class JwtUtil {
        //自定密钥,最好搞长一点
        public static final String tokenKey = "jay2021";
        /*
        生成票证
         */
        public static String getSign(HashMap<String,Object> headMap,HashMap<String,String> claimMap,int days){
            LocalDateTime localDateTime = LocalDateTime.now().plus(days, ChronoUnit.DAYS);
            Date date = LocalDateTimeUtil.localDateTimeToDate(localDateTime);
            JWTCreator.Builder builder = JWT.create().withHeader(headMap);
            claimMap.forEach((key, value) -> {
                builder.withClaim(key, value);
            });
            builder.withExpiresAt(date);
            String token = builder.sign(Algorithm.HMAC256(tokenKey));
            return token;
        }
        /*
        获取token信息,token不对会异常
         */
        public static DecodedJWT verify(String token){
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(tokenKey)).build().verify(token);
            return verify;
        }
    }
    

    3、日期工具类LocalDateTimeUtil

    package com.jay.SpringBootStudy8.utils;
    
    import java.time.Instant;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.util.Date;
    
    public class LocalDateTimeUtil {
        /**
         * LocalDateTime转毫秒时间戳
         * @param localDateTime LocalDateTime
         * @return 时间戳
         */
        public static Long localDateTimeToTimestamp(LocalDateTime localDateTime) {
            try {
                ZoneId zoneId = ZoneId.systemDefault();
                Instant instant = localDateTime.atZone(zoneId).toInstant();
                return instant.toEpochMilli();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 时间戳转LocalDateTime
         * @param timestamp 时间戳
         * @return LocalDateTime
         */
        public static LocalDateTime timestampToLocalDateTime(long timestamp) {
            try {
                Instant instant = Instant.ofEpochMilli(timestamp);
                ZoneId zone = ZoneId.systemDefault();
                return LocalDateTime.ofInstant(instant, zone);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * Date转LocalDateTime
         * @param date Date
         * @return LocalDateTime
         */
        public static LocalDateTime dateToLocalDateTime(Date date) {
            try {
                Instant instant = date.toInstant();
                ZoneId zoneId = ZoneId.systemDefault();
                return instant.atZone(zoneId).toLocalDateTime();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * LocalDateTime转Date
         * @param localDateTime LocalDateTime
         * @return Date
         */
        public static Date localDateTimeToDate(LocalDateTime localDateTime) {
            try {
                ZoneId zoneId = ZoneId.systemDefault();
                ZonedDateTime zdt = localDateTime.atZone(zoneId);
                return Date.from(zdt.toInstant());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    4、JWT拦截器,在请求头的Authorization中携带token

    package com.jay.SpringBootStudy8.config;
    
    import com.auth0.jwt.exceptions.AlgorithmMismatchException;
    import com.auth0.jwt.exceptions.SignatureVerificationException;
    import com.auth0.jwt.exceptions.TokenExpiredException;
    import com.auth0.jwt.interfaces.DecodedJWT;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.jay.SpringBootStudy8.utils.JwtUtil;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import java.util.HashMap;
    
    public class JWTInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
            HashMap<String,Object> res = new HashMap<>();
            res.put("state",false);
            String authStr = request.getHeader("Authorization");
            try {
                DecodedJWT verify = JwtUtil.verify(authStr);
                res.put("state",true);
                return true;
            }catch (SignatureVerificationException e) {
                e.printStackTrace();//无效签名
                res.put("msg","无效签名");
            }catch (TokenExpiredException e){
                e.printStackTrace();//token过期
                res.put("msg","token过期");
            }catch (AlgorithmMismatchException e){
                e.printStackTrace();//算法不一致
                res.put("msg","算法不一致");
            }catch (Exception e){
                e.printStackTrace();//token无效
                res.put("msg","token无效");
            }
            String json = new ObjectMapper().writeValueAsString(res);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().println(json);
            return false;
        }
    }
    

    5、注册拦截器

    package com.jay.SpringBootStudy8.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.LocaleResolver;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class CustomerMvcConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new JWTInterceptor()).addPathPatterns("/scanner/getCompanies");
        }
    }
    

    6、登录生成token、获取token信息、验证拦截器,登录使用的是Shiro

    package com.jay.SpringBootStudy8.controller;
    
    import com.auth0.jwt.interfaces.Claim;
    import com.auth0.jwt.interfaces.DecodedJWT;
    import com.jay.SpringBootStudy8.pojo.SysUser;
    import com.jay.SpringBootStudy8.utils.JwtUtil;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.ByteSource;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestHeader;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @RestController
    public class ScannerController {
        /*
        登录,生成token
         */
        @PostMapping("/scanner/login")
        public HashMap<String,Object> login(String name, String pwd) {
            HashMap<String,Object> res = new HashMap<>();
            res.put("state",false);
            //MD5加密
            ByteSource credentialsSalt = ByteSource.Util.bytes(name);
            Object obj = new SimpleHash("MD5", pwd, credentialsSalt, 1);
            String pwd2 = obj.toString();
            //获取当前用户
            Subject subject = SecurityUtils.getSubject();
            //封装登录数据
            UsernamePasswordToken token = new UsernamePasswordToken(name, pwd2);
            try {
                //执行登录方法
                subject.login(token);
                Session session = subject.getSession();
                SysUser user = (SysUser) session.getAttribute("user");
                // 登录成功,生成票证
                HashMap<String,Object> headMap = new HashMap<>();
                HashMap<String,String> claimMap = new HashMap<>();
                claimMap.put("userId",Integer.toString(user.getId()));
                claimMap.put("userName",user.getUserName());
                String signStr = JwtUtil.getSign(headMap,claimMap,7);
                res.put("state",true);
                res.put("msg","登录成功");
                res.put("token",signStr);
            } catch (UnknownAccountException e) {
                res.put("msg","用户名不存在");
            } catch (IncorrectCredentialsException e) {
                res.put("msg","密码错误");
            }
            return res;
        }
        /*
        获取token信息
         */
        @PostMapping("/scanner/checkToken")
        public Map<String, String> checkToken(@RequestHeader("Authorization")String authStr){
            DecodedJWT verify = JwtUtil.verify(authStr);
            Map<String, Claim> claims = verify.getClaims();
            Map<String,String> res = new HashMap<>();
            claims.forEach((key,value)->{
                res.put(key,value.asString());
            });
            return res;
        }
        /*
        拦截请求
         */
        @PostMapping("/scanner/getCompanies")
        public Map<String,String> getCompanies(){
            Map<String,String> res = new HashMap<>();
            res.put("ali","阿里巴巴");
            res.put("baidu","百度");
            return  res;
        }
    }
    

      视频:https://www.bilibili.com/video/BV1i54y1m7cP?p=1

  • 相关阅读:
    线段树区间最大子段和
    NTT数论变换
    cdq分治·三维偏序问题
    线段树区间开方
    怎么联系$zcy$呢?
    题解 CF375D 【Tree and Queries】
    点分治模板
    Good Bye 2018题解
    Hello 2019题解
    Codeforces Round #525 (Div. 2)题解
  • 原文地址:https://www.cnblogs.com/xsj1989/p/15176803.html
Copyright © 2011-2022 走看看