最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot與JWT整合方式

 更新時(shí)間:2024年11月28日 09:58:11   作者:BLUcoding  
文章介紹了如何在Spring?Boot項(xiàng)目中整合JWT(JSON?Web?Token),包括JWT的結(jié)構(gòu)、使用方法、測試以及配置,主要內(nèi)容涵蓋了依賴配置、數(shù)據(jù)庫表設(shè)計(jì)、實(shí)體類、數(shù)據(jù)訪問層、服務(wù)層、JWT工具類、攔截器配置和控制器測試等多個(gè)方面

SpringBoot與JWT整合

JWT的結(jié)構(gòu)

Header(頭):包含令牌的類型與使用的簽名算法,它會使用Base64進(jìn)行編碼

{
	"alg": "HS265",
	"typ": "JWT"
}

Payload(有效負(fù)載): 包含聲明(有關(guān)用戶實(shí)體和其他數(shù)據(jù)的聲明),使用Base64進(jìn)行編碼Base64是一種可逆的編碼,因此不要在負(fù)載里存入敏感數(shù)據(jù)!

{
	"id": "1",
	"name": "BLU",
	"admin": true
}

Signature(簽名):使用編碼后的header和payload以及一個(gè)指定密鑰,然后使用header中指定的算法(HS265)進(jìn)行簽名.

簽名的作用是保證JWT沒有被篡改過

JWT的使用測試

  • 依賴:
<dependency>
	<groupId>com.auth0</groupId>
	<artifactId>java-jwt</artifactId>
	<version>3.4.0</version>
</dependency>
  • 測試:
@Test
void getToken() {

	//HashMap<String,Object> map = new HashMap<String, Object>();
	Calendar instance = Calendar.getInstance();
	instance.add(Calendar.SECOND, 60);
	String token = JWT.create()
			//.withHeader(map)
			//設(shè)置Payload
			.withClaim("userId", 10)
			.withClaim("username", "BLU")
			//設(shè)置token過期時(shí)間(60s)
			.withExpiresAt(instance.getTime())
			//設(shè)置簽名
			.sign(Algorithm.HMAC256("!@#$%^&*"));
	System.out.println(token);

}
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDA3NDA2MTUsInVzZXJJZCI6MTAsInVzZXJuYW1lIjoiQkxVIn0.0re-tA4dQm4blGhn1DvpnUl7Lrz_EWXwn8LfRbWQXCU
@Test
void TokenVerify() {
	//創(chuàng)建驗(yàn)證對象
	JWTVerifier verifier = JWT.require(Algorithm.HMAC256("!@#$%^&*")).build();
	DecodedJWT verify = verifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDA3NDA2MTUsInVzZXJJZCI6MTAsInVzZXJuYW1lIjoiQkxVIn0.0re-tA4dQm4blGhn1DvpnUl7Lrz_EWXwn8LfRbWQXCU");
	System.out.println(verify.getClaim("userId").asInt());
	System.out.println(verify.getClaims().get("username").asString());
	System.out.println("過期時(shí)間:"+verify.getExpiresAt());	
}

10
BLU
過期時(shí)間:Tue Sep 22 10:10:15 CST 2020

SpringBoot與JWT整合

  • 依賴
<dependencies>
	<dependency>
		<groupId>com.auth0</groupId>
		<artifactId>java-jwt</artifactId>
		<version>3.4.0</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.mybatis.spring.boot</groupId>
		<artifactId>mybatis-spring-boot-starter</artifactId>
		<version>2.1.2</version>
	</dependency>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
		<version>1.1.22</version>
	</dependency>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
		<exclusions>
			<exclusion>
				<groupId>org.junit.vintage</groupId>
				<artifactId>junit-vintage-engine</artifactId>
			</exclusion>
		</exclusions>
	</dependency>
</dependencies>
  • 配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jwt?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456

mybatis.type-aliases-package=com.blu.entity
mybatis.mapper-locations=classpath:mapper/*.xml

logging.level.com.blu.dao=debug
  • 數(shù)據(jù)庫user表:

  • 實(shí)體類:
package com.blu.entity;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain=true)
public class User {
	private String id;
	private String name;
	private String password;
}
  • UserDao:
package com.blu.dao;

import org.apache.ibatis.annotations.Mapper;
import com.blu.entity.User;

@Mapper
public interface UserDao {
	User login(User user);
}
  • UserMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.blu.dao.UserDao">
	<select id="login" parameterType="User" resultType="User">
		select * from user where name= #{name} and password= #{password}
	</select>
</mapper>
  • UserService:
package com.blu.service;

import com.blu.entity.User;

public interface UserService {
	User login(User user);
}
  • UserServiceImpl:
package com.blu.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.blu.dao.UserDao;
import com.blu.entity.User;
import com.blu.service.UserService;

@Service
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserDao userDao;

	@Override
	public User login(User user) {
		User userDB = userDao.login(user);
		if(userDB!=null) {
			return userDB;
		}
		throw new RuntimeException("認(rèn)證失敗!");
	}
	
}
  • JWT的工具類封裝:
package com.blu.utils;

import java.util.Calendar;
import java.util.Map;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

public class JWTUtils {
	
	private static final String SIGN= "!@#$%^&*123456789";
	
	
	/**
	 * 生成Token
	 */
	public static String getToken(Map<String,String> map) {
		Calendar instance = Calendar.getInstance();
		instance.add(Calendar.DATE, 7);
		//創(chuàng)建JWTBuilder
		JWTCreator.Builder builder = JWT.create();
		//設(shè)置payload
		map.forEach((k,v)->{
			builder.withClaim(k, v);
		});
		//設(shè)置過期時(shí)間和簽名,生成token
		String token = builder.withExpiresAt(instance.getTime())
			.sign(Algorithm.HMAC256(SIGN));
		return token;
	}
	
	/**
	 * 驗(yàn)證token
	 */
	public static void TokenVerify(String token) {
		JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
	}
	
	/**
	 * 獲取token信息 
	 */
	public static DecodedJWT getTokenInfo(String token) {
		DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
		return verify;
	}

}
  • JWTInterceptor 攔截器
package com.blu.interceptors;

import java.util.HashMap;
import java.util.Map;

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

import org.springframework.web.servlet.HandlerInterceptor;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.blu.utils.JWTUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JWTInterceptor implements HandlerInterceptor {
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//獲取請求頭中的token
		String token = request.getHeader("token");
		Map<String,Object> map = new HashMap<String, Object>();
		try {
			JWTUtils.TokenVerify(token);
			//放行請求
			return true;
		} catch (SignatureVerificationException e) {
			map.put("msg", "無效簽名");
			e.printStackTrace();
		} catch (TokenExpiredException e) {
			map.put("msg", "token已過期");
			e.printStackTrace();
		} catch (AlgorithmMismatchException e) {
			map.put("msg", "算法不一致");
			e.printStackTrace();
		} catch (Exception e) {
			map.put("msg", "token無效");
			e.printStackTrace();
		}
		map.put("state",false);
		//使用jackson將map轉(zhuǎn)為json
		String json = new ObjectMapper().writeValueAsString(map);
		response.setContentType("application/json;charset=UTF-8");
		response.getWriter().print(json);
		return false;
	}

}
  • InterceptorConfig 配置類
package com.blu.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.blu.interceptors.JWTInterceptor;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new JWTInterceptor())
				.addPathPatterns("/**")
				.excludePathPatterns("/user/login");
	}
	
}
  • UserController
package com.blu.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

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.blu.entity.User;
import com.blu.service.UserService;
import com.blu.utils.JWTUtils;

import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@GetMapping("/user/login")
	public Map<String,Object> login(User user){
		log.info("用戶名:[{}]",user.getName());
		log.info("密碼:[{}]",user.getPassword());
		Map<String,Object> map = new HashMap<String, Object>();
		try {
			User userDB = userService.login(user);
			Map<String,String> payload = new HashMap<String, String>();
			payload.put("id", userDB.getId());
			payload.put("name", userDB.getName());
			String token = JWTUtils.getToken(payload);
			map.put("state",true);
			map.put("msg","認(rèn)證成功");
			map.put("token", token);
		} catch (Exception e) {
			map.put("state",false);
			map.put("msg",e.getMessage());
		}
		return map;
	}
	
	@PostMapping("/user/test")
	public Map<String,Object> test(HttpServletRequest request){
		
		String token = request.getHeader("token");
		DecodedJWT tokenInfo = JWTUtils.getTokenInfo(token);
		log.info("用戶id:[{}]",tokenInfo.getClaim("id").asString());
		log.info("用戶名:[{}]",tokenInfo.getClaim("name").asString());
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("state", true);
		map.put("msg","請求成功");
		return map;
	}
	
}
  • 測試

登錄獲取token:

測試錯(cuò)誤的token:

測試正確的token:

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring定時(shí)任務(wù)只執(zhí)行一次的原因分析與解決方案

    Spring定時(shí)任務(wù)只執(zhí)行一次的原因分析與解決方案

    在使用Spring的@Scheduled定時(shí)任務(wù)時(shí),你是否遇到過任務(wù)只執(zhí)行一次,后續(xù)不再觸發(fā)的情況?這種情況可能由多種原因?qū)е?如未啟用調(diào)度、線程池問題、異常中斷等,本文將深入分析Spring定時(shí)任務(wù)只執(zhí)行一次的原因,并提供完整的解決方案,需要的朋友可以參考下
    2025-03-03
  • Java中的RabbitMQ使用場景和實(shí)踐完全指南

    Java中的RabbitMQ使用場景和實(shí)踐完全指南

    本文涵蓋了RabbitMQ在Java中的主要使用場景和實(shí)踐方法,在實(shí)際應(yīng)用中,還需要根據(jù)具體的業(yè)務(wù)需求和系統(tǒng)架構(gòu)進(jìn)行適當(dāng)?shù)恼{(diào)整和優(yōu)化,本文結(jié)合代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-08-08
  • Java調(diào)用shell命令涉及管道、重定向時(shí)不生效問題及解決

    Java調(diào)用shell命令涉及管道、重定向時(shí)不生效問題及解決

    這篇文章主要介紹了Java調(diào)用shell命令涉及管道、重定向時(shí)不生效問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • java實(shí)現(xiàn)sunday算法示例分享

    java實(shí)現(xiàn)sunday算法示例分享

    Sunday算法的思想和BM算法中的壞字符思想非常類似。差別只是在于Sunday算法在匹配失敗之后,是取目標(biāo)串中當(dāng)前和Pattern字符串對應(yīng)的部分后面一個(gè)位置的字符來做壞字符匹配,寫了個(gè)小例子來實(shí)現(xiàn)以下這個(gè)算法
    2014-01-01
  • 關(guān)于@Bean的使用方式

    關(guān)于@Bean的使用方式

    這篇文章主要介紹了關(guān)于@Bean的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 關(guān)于Spring源碼深度解析(AOP功能源碼解析)

    關(guān)于Spring源碼深度解析(AOP功能源碼解析)

    這篇文章主要介紹了關(guān)于Spring源碼深度解析(AOP功能源碼解析),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • SpringBoot中的自動配置原理詳解

    SpringBoot中的自動配置原理詳解

    這篇文章主要介紹了SpringBoot中的自動配置原理詳解,springboot的自動配置類直觀的表現(xiàn)就是通過一系列的注解,使得springboot項(xiàng)目在啟動的時(shí)候從配置文件中加載需要自動配置的類,注入容器中,需要的朋友可以參考下
    2024-01-01
  • Java?多個(gè)文件生成zip包、下載zip包的實(shí)現(xiàn)代碼

    Java?多個(gè)文件生成zip包、下載zip包的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java?多個(gè)文件生成zip包、下載zip包,包括文件上傳,文件下載,多個(gè)文件打成zip包的操作代碼,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • SpringBoot下使用定時(shí)任務(wù)的方式全揭秘(6種)

    SpringBoot下使用定時(shí)任務(wù)的方式全揭秘(6種)

    這篇文章主要介紹了SpringBoot下使用定時(shí)任務(wù)的方式全揭秘(6種),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • ?java簡介及環(huán)境搭建

    ?java簡介及環(huán)境搭建

    這篇文章主要介紹了java簡介及環(huán)境搭建,文章主要介紹Java的發(fā)展史及環(huán)境搭建,對正在學(xué)Java的你有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-03-03

最新評論

西青区| 阜城县| 中卫市| 寿光市| 会东县| 巴塘县| 达孜县| 丰顺县| 延长县| 大化| 乐东| 加查县| 蓬溪县| 临沂市| 阿鲁科尔沁旗| 秦安县| 昭觉县| 莱西市| 朝阳县| 甘孜| 长武县| 吴川市| 巴林右旗| 望都县| 江津市| 文成县| 大宁县| 沐川县| 清徐县| 汨罗市| 高邑县| 临邑县| 区。| 鄢陵县| 酒泉市| 肥乡县| 鄄城县| 香格里拉县| 梅州市| 察哈| 武义县|