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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM