Java如何實現(xiàn)登錄token令牌
一、流程圖

二、Token
1、token是一種客戶端認證機制,是一個經(jīng)過加密的字符串,安全性強,支持跨域
2、用戶第一次登錄,服務(wù)器通過數(shù)據(jù)庫校驗其UserId和Password合法,則再根據(jù)隨機數(shù)字+userid+當(dāng)前時間戳再經(jīng)過DES加密生成一個token串
- 當(dāng)然具體生成token的方式是開發(fā)自己定義的
3、token的生成一般是采用uuid保證唯一性,當(dāng)用戶登錄時為其生成唯一的token,存儲一般保存在數(shù)據(jù)庫中
- token過期時間采用把token二次保存在cookie或session里面,根據(jù)cookie和session的過期時間去維護token的過期時間
4、Token是在服務(wù)端產(chǎn)生的。如果前端使用用戶名/密碼向服務(wù)端請求認證,服務(wù)端認證成功,那么在服務(wù)端會返回Token給前端。前端可以在每次請求的時候帶上Token證明自己的合法地位
5、Token,就是令牌,最大的特點就是隨機性,不可預(yù)測。一般黑客或軟件無法猜測出來
三、分析
建立一個token令牌,在用戶登錄時候給用戶一個獨特得令牌值,登錄時候嘚賦值這個令牌
在SpringBoot項目中建立一個Util文件夾
文件夾下建立TokenUtil.java文件
public class TokenUtil {
private static Map<String, User> tokenMap = new HashMap<>();
public static String generateToken(User user){
//生成唯一不重復(fù)的字符串
String token = UUID.randomUUID().toString();
tokenMap.put(token,user);
return token;
}
/**
* 驗證token是否合法
* @param token
* @return
*/
public static boolean verify(String token){
return tokenMap.containsKey(token);
}
public static User gentUser(String token){
return tokenMap.get(token);
}
public static void main(String[] args) {
for (int i = 0; i < 20; i++){
System.out.println(UUID.randomUUID().toString());
}
}
}用戶登錄得UserController.java
@Api( tags = {"用戶模塊接口"})
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private HttpSession session;
@ApiOperation("登錄接口")
@RequestMapping(value = "login",method ={RequestMethod.POST,RequestMethod.GET})
public Map<String,Object> login(User user){
Map<String,Object> map = new HashMap<>();
map.put("code",0);
if(StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword()) ){
map.put("msg","用戶或者密碼為空!");
return map;
}
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",user.getUsername())
.eq("password",user.getPassword());
User userDb = userService.getOne(queryWrapper);
if(userDb != null){
String token= TokenUtil.generateToken(userDb);
map.put("code",1);
map.put("data",userDb);
map.put("token",token);
session.setAttribute("username",userDb.getUsername());
}else{
map.put("msg","用戶名或密碼錯誤!");
}
return map;
}
@ApiImplicitParams(
{
@ApiImplicitParam(name = "id",
value = "用戶id", required = true,
dataType = "Long"),
@ApiImplicitParam(name = "name",
value = "測試名字",
dataType = "string")
}
)
@ApiOperation("根據(jù)id查詢用戶信息")
@RequestMapping(value="getById",method ={RequestMethod.POST,RequestMethod.GET})
public User getById(Long id ,String name){
System.out.println(name);
return userService.getById(id);
}
}在攔截器上操作 interceptor下面LoginInterceptor.java
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private HttpSession httpSession;
//Controller邏輯執(zhí)行之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle....");
String uri = request.getRequestURI();
System.out.println("當(dāng)前路徑:"+uri);
/**
* HandlerMethod=>Controller中標注@RequestMapping的方法
* 需要配置靜態(tài)資源不攔截時,添加這塊邏輯 => 前后端分離項目
*
*/
// 是我們的conrtoller中的方法
if (!(handler instanceof HandlerMethod)) {
return true;
}
String token = request.getHeader("qcby-token");
if (!TokenUtil.verify(token)) {
// 未登錄跳轉(zhuǎn)到登錄界面
throw new RuntimeException("no login!");
} else {
return true;
}
}
//Controller邏輯執(zhí)行完畢但是視圖解析器還未進行解析之前
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle....");
}
//Controller邏輯和視圖解析器執(zhí)行完畢
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion....");
}
}四、運行結(jié)果
http://localhost:8080/

http://localhost:8080/user/login?username=admin&password=123456

記住這個令牌
60227b0e-bdbb-47d9-9df4-f56163cb529d
在postman中

寫入令牌,輸出成功

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring中@Import的各種用法以及ImportAware接口詳解
這篇文章主要介紹了Spring中@Import的各種用法以及ImportAware接口詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
SpringBoot中的ThreadLocal保存請求用戶信息的實例demo
線程局部變量,創(chuàng)建一個線程變量后,針對這個變量可以讓每個線程擁有自己的變量副本,每個線程是訪問的自己的副本,與其他線程的相互獨立,本文介紹SpringBoot中的ThreadLocal保存請求用戶信息,需要的朋友可以參考下2024-05-05
SpringBoot淺析安全管理之Spring Security配置
安全管理是軟件系統(tǒng)必不可少的的功能。根據(jù)經(jīng)典的“墨菲定律”——凡是可能,總會發(fā)生。如果系統(tǒng)存在安全隱患,最終必然會出現(xiàn)問題,這篇文章主要介紹了SpringBoot安全管理Spring Security基本配置2022-08-08
Spring?boot?自定義?Starter及自動配置的方法
Starter?組件是?Spring?boot?的一個核心特性,Starter組件的出現(xiàn)極大的簡化了項目開發(fā),這篇文章主要介紹了Spring?boot?自定義?Starter?及?自動配置,需要的朋友可以參考下2022-12-12
Java使用正則表達式去除小數(shù)點后面多余的0功能示例
這篇文章主要介紹了Java使用正則表達式去除小數(shù)點后面多余的0功能,結(jié)合具體實例形式分析了java字符串正則替換相關(guān)操作技巧,需要的朋友可以參考下2017-06-06

