一、實(shí)現(xiàn)原理
1、token的存儲(chǔ)
當(dāng)用戶登錄時(shí),將<token, userInfo>存入redis緩存中,以便鑒權(quán)與獲取用戶信息。
2、發(fā)送請(qǐng)求
每次發(fā)送請(qǐng)求時(shí)將token放入請(qǐng)求頭中,令key為“Authorization”或其他值。
3、獲取請(qǐng)求頭部
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
4、用戶請(qǐng)求頭部攜帶的token在redis中獲得userInfo
二、導(dǎo)入依賴
1、redis相關(guān)依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2、fastjson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
3、mybatis-plus
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
三、配置文件
server:
port: 10002
spring:
datasource:
url: jdbc:mysql://localhost:3306/myDB?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: <用戶名>
password: <密碼>
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
#數(shù)據(jù)庫索引
database: 0
host: 127.0.0.1
password: <密碼>
jedis:
pool:
max-idle: 300
max-active: 600
max-wait: 1000
timeout: 3600
port: 6379
pool:
maxTotal: 1000
testOnBorrow: true
四、代碼實(shí)現(xiàn)
1、RedisUtil
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* redis工具類
*/
@Component
public class RedisUtil {
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 指定緩存失效時(shí)間
*
* @param key 鍵
* @param time 時(shí)間(秒)
* @return true or false
*/
public Boolean expire(final String key, final long time) {
stringRedisTemplate.afterPropertiesSet();
try {
if (time > 0) {
stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (final Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通緩存獲取
*
* @param key 鍵
* @return 值
*/
public Object get(final String key) {
stringRedisTemplate.afterPropertiesSet();
return key == null ? null : stringRedisTemplate.opsForValue().get(key);
}
/**
* 普通緩存放入
*
* @param key 鍵
* @param value 值
* @return true成功 false失敗
*/
public Boolean set(final String key, final String value) {
stringRedisTemplate.afterPropertiesSet();
try {
stringRedisTemplate.opsForValue().set(key, value);
return true;
} catch (final Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通緩存放入并設(shè)置時(shí)間
*
* @param key 鍵
* @param value 值
* @param time 時(shí)間(秒) time要大于0 如果time小于等于0 將設(shè)置無限期
* @return true成功 false 失敗
*/
public Boolean set(final String key, final String value, final long time) {
stringRedisTemplate.afterPropertiesSet();
try {
if (time > 0) {
stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (final Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 刪除鍵
* @param key 鍵
* @return true or false
*/
public Boolean del(final String key) {
stringRedisTemplate.afterPropertiesSet();
try {
stringRedisTemplate.opsForHash().delete(key);
return true;
} catch (final Exception e) {
e.printStackTrace();
return false;
}
}
}
2、TokenUtil
import java.util.UUID;
public class TokenUtil {
public static String generateToken() {
//生成唯一不重復(fù)的字符串
return UUID.randomUUID().toString();
}
}
3、UserHelper
import com.alibaba.fastjson.JSONObject;
import com.example.commons.utils.MyStringUtils;
import com.example.commons.utils.ObjectUtil;
import com.example.commons.utils.RedisUtil;
import com.example.commons.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Component
public class UserHelper {
@Autowired
private RedisUtil redisUtil;
/**
* 獲取當(dāng)前用戶的信息
* @return userVO
*/
public UserVO getCurrentUser() {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (sra == null) {
return null;
}
HttpServletRequest request = sra.getRequest();
return getCurrentUser(request);
}
/**
* 通過請(qǐng)求獲取當(dāng)前用戶信息
* @param request 請(qǐng)求
* @return userVO
*/
public UserVO getCurrentUser(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (MyStringUtils.isBlank(token)) {
return null;
}
return getCurrentUserByToken(token);
}
/**
* 通過token獲取當(dāng)前用戶信息
* @param token token
* @return userVO
*/
public UserVO getCurrentUserByToken(String token) {
String context = (String) redisUtil.get(token);
if (MyStringUtils.isBlank(context)) {
return null;
}
try {
return JSONObject.parseObject(context, UserVO.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 獲取當(dāng)前用戶的id
* @return 用戶id
*/
public Long getCurrentUserId() {
UserVO userVO = getCurrentUser();
if (ObjectUtil.isNull(userVO)) {
return null;
}
return userVO.getId();
}
/**
* 獲取當(dāng)前請(qǐng)求
* @return request
*/
public HttpServletRequest getHttpServletRequest() {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (sra == null) {
return null;
}
return sra.getRequest();
}
}
以上代碼中提到的UserVO、MyStringUtil、ObjectUtil均為本人自定義,比較簡單且與主題關(guān)聯(lián)不大,就不占用篇幅了。
4、登錄
@PostMapping("/login")
public RestResponseEntity Login(@RequestParam("id") Long id) {
// 此處簡化操作,只要用戶id存在即視為登錄成功
User user = userService.getUserById(id);
if (ObjectUtil.isNull(user)) {
return RestResponseEntity.fail("登錄失敗");
}
UserVO userVO = new UserVO();
userVO.setId(user.getId());
userVO.setName(user.getUName());
// 將userVO序列化轉(zhuǎn)成json字符串
String userContext = JSON.toJSONString(userVO);
// 隨機(jī)生成一個(gè)token
String token = TokenUtil.generateToken();
// 將token與userContext存入redis
redisUtil.set(token, userContext);
return RestResponseEntity.success(token); // 此處響應(yīng)體為自定義
}
5、調(diào)用getCurrentUser實(shí)例
import com.example.commons.vo.UserVO;
import com.example.reader.Helper.UserHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserHelper userHelper;
@GetMapping("/getUser")
public UserVO getUser() {
return userHelper.getCurrentUser();
}
}
?6、測(cè)試
(1)登錄測(cè)試
請(qǐng)求成功,token與userInfo也已寫入redis
(2)獲得當(dāng)前用戶信息
五、總結(jié)
用這種方法獲取當(dāng)前用戶信息,只需要一句簡單的文章來源:http://www.zghlxwxcb.cn/news/detail-451269.html
UserVO userVO =?userHelper.getCurrentUser();
而不需要在controller或者其他業(yè)務(wù)代碼中獲取http頭部,更加整潔。并且將一些用戶常用的信息存入redis中,可以減少檢索數(shù)據(jù)庫的次數(shù),一定程度上可以提高效率。文章來源地址http://www.zghlxwxcb.cn/news/detail-451269.html
到了這里,關(guān)于Springboot通過請(qǐng)求頭獲取當(dāng)前用戶信息的一種方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!