欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot框架集成token實現(xiàn)登錄校驗功能

 更新時間:2019年08月23日 08:51:12   作者:Snow、楊  
這篇文章主要為大家詳細介紹了SpringBoot框架集成token實現(xiàn)登錄校驗功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

簡介

公司新項目,需要做移動端(Android和IOS),登錄模塊,兩個移動端人員提出用token來校驗登錄狀態(tài),一臉懵懵的,沒做過,對于token的基本定義都模棱兩可,然后查資料查查查,最終OK完成,寫篇博客記錄一下

思路:

1、基于session登錄

基于session的登錄(有回話狀態(tài)),用戶攜帶賬號密碼發(fā)送請求向服務(wù)器,服務(wù)器進行判斷,成功后將用戶信息放入session,用戶發(fā)送請求判斷session中是否有用戶信息,有的話放行,沒有的話進行攔截,但是考慮到時App產(chǎn)品,牽扯到要判斷用戶的session,需要sessionID,還要根據(jù)sessionId來獲取session,在進行校驗,還有sessionId的一個存儲等等,所以沒考慮用session

2、基于token登錄

基于token的登錄,是不存在回話狀態(tài),大概思路,在用戶初次等路的時候,校驗用戶賬號密碼,成功后給其生成一個token,token=用戶ID+時間戳+過期時間+一個自己平臺規(guī)定的簽名,使用jjwt生成一個令牌,然后對其進行存庫,用戶每次訪問接口,都會在頭部Headers中帶上token,后來攔截器對其進行攔截,如果token為空或錯誤則讓其登錄,如果有token,獲取token進行其解析,取出里面的用戶ID,根據(jù)用戶ID查詢數(shù)據(jù)庫中所存token,判斷其是否正確,正確使其登錄,錯誤則提示登錄,大致思路就是這樣,下面開始代碼

導入jar包

<!-- 生成token -->
<dependency>
 <groupId>io.jsonwebtoken</groupId>
 <artifactId>jjwt</artifactId>
 <version>0.9.0</version>
</dependency>

開發(fā)步驟

1、創(chuàng)建token庫

2、創(chuàng)建token實體類

package com.prereadweb.user.entity;
 
import lombok.Data;
 
/**
 * @Description: Token實體類
 * @author: Yangxf
 * @date: 2019/4/14 12:53
 */
@Data
public class TokenEntity {
 
 /* tokenId */
 private Long id;
 
 /* 用戶ID */
 private Long userId;
 
 /* 刷新時間 */
 private int buildTime;
 
 /* token */
 private String token;
 
}

3、編寫token的三個方法(添加、查詢、修改)

package com.prereadweb.user.mapper;
 
import com.prereadweb.user.entity.TokenEntity;
import org.apache.ibatis.annotations.Mapper;
 
/**
 * @Description: Token數(shù)據(jù)庫持久層接口
 * @author: Yangxf
 * @date: 2019/4/14 13:00
 */
@Mapper
public interface TokenMapper {
 
 /* 添加token */
 void addToken(TokenEntity token);
 
 /* 修改token */
 void updataToken(TokenEntity token);
 
 /* 查詢token */
 TokenEntity findByUserId(Long userId);
 
}

4、創(chuàng)建攔截器

package com.prereadweb.user.interceptor;
 
import com.prereadweb.user.entity.TokenEntity;
import com.prereadweb.user.mapper.TokenMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
 
/**
 * @Description:攔截器
 * @author: Yangxf
 * @date: 2019/4/14 12:58
 */
public class LoginInterceptor implements HandlerInterceptor {
 
 @Autowired
 protected TokenMapper tokenMapper;
 //提供查詢
 @Override
 public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
  throws Exception {}
 @Override
 public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
  throws Exception {}
 @Override
 public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
 //此處為不需要登錄的接口放行
 if (arg0.getRequestURI().contains("/login") || arg0.getRequestURI().contains("/register") || arg0.getRequestURI().contains("/error") || arg0.getRequestURI().contains("/static")) {
  return true;
 }
 //權(quán)限路徑攔截
 //PrintWriter resultWriter = arg1.getOutputStream();
 // TODO: 有時候用PrintWriter 回報 getWriter() has already been called for this response
 //換成ServletOutputStream就OK了
 arg1.setContentType("text/html;charset=utf-8");
 ServletOutputStream resultWriter = arg1.getOutputStream();
 final String headerToken=arg0.getHeader("token");
 //判斷請求信息
 if(null==headerToken||headerToken.trim().equals("")){
  resultWriter.write("你沒有token,需要登錄".getBytes());
  resultWriter.flush();
  resultWriter.close();
  return false;
 }
 //解析Token信息
 try {
  Claims claims = Jwts.parser().setSigningKey("preRead").parseClaimsJws(headerToken).getBody();
  String tokenUserId=(String)claims.get("userId");
  long iTokenUserId = Long.parseLong(tokenUserId);
  //根據(jù)客戶Token查找數(shù)據(jù)庫Token
  TokenEntity myToken= tokenMapper.findByUserId(iTokenUserId);
 
  //數(shù)據(jù)庫沒有Token記錄
  if(null==myToken) {
  resultWriter.write("我沒有你的token?,需要登錄".getBytes());
  resultWriter.flush();
  resultWriter.close();
  return false;
  }
  //數(shù)據(jù)庫Token與客戶Token比較
  if( !headerToken.equals(myToken.getToken()) ){
  resultWriter.print("你的token修改過?,需要登錄");
  resultWriter.flush();
  resultWriter.close();
  return false;
  }
  //判斷Token過期
  Date tokenDate= claims.getExpiration();
  int overTime=(int)(new Date().getTime()-tokenDate.getTime())/1000;
  if(overTime>60*60*24*3){
  resultWriter.write("你的token過期了?,需要登錄".getBytes());
  resultWriter.flush();
  resultWriter.close();
  return false;
  }
 
 } catch (Exception e) {
  resultWriter.write("反正token不對,需要登錄".getBytes());
  resultWriter.flush();
  resultWriter.close();
  return false;
 }
 //最后才放行
 return true;
 }
 
}

5、配置攔截器

package com.prereadweb.user.config;
 
import com.prereadweb.user.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
/**
 * @Description: 攔截器配置
 * @author: Yangxf
 * @date: 2019/4/14 13:09
 */
@Configuration
public class LoginConfiguration implements WebMvcConfigurer {
 
 /**
 * @Function: 這個方法才能在攔截器中自動注入查詢數(shù)據(jù)庫的對象
 * @author: YangXueFeng
 * @Date: 2019/4/14 13:10
 */
 @Bean
 LoginInterceptor loginInterceptor() {
 return new LoginInterceptor();
 }
 
 /**
 * @Function: 配置生成器:添加一個攔截器,攔截路徑為login以后的路徑
 * @author: YangXueFeng
 * @Date: 2019/4/14 13:10
 */
 @Override
 public void addInterceptors(InterceptorRegistry registry ){
 registry.addInterceptor(loginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/register", "/static");
 }
}

6、登錄

controller層

 @RequestMapping("/getlogin")
 public Object login(@Param("..") LoginQueryForm loginForm) {
 return userViewService.login(loginForm);
 }

serrvice層

@Override
 public Map<String, Object> login(LoginQueryForm loginForm) {
 
 Map<String, Object> map = new HashMap<>();
 //手機驗證碼登錄
 if(!Util.isEmpty(loginForm.getPhoneCode())) {
  return phoneCodeLogin(loginForm, map);
 }
 //判斷用戶信息為空
 if (Util.isEmpty(loginForm.getPhone()) || Util.isEmpty(loginForm.getLoginPwd())) {
  return checkParameter(map);
 }
 //根據(jù)手機號查詢user對象
 UserEntity user = userMapper.getUser(loginForm.getPhone());
 
 //判斷用戶不存在
 if (Util.isEmpty(user)) {
  map.put("code", UserStatusEnum.USER_NON_EXISTENT.intKey());
  map.put("msg", UserStatusEnum.USER_NON_EXISTENT.value());
  return map;
 }
 /* 判斷密碼 */
 if(!MD5Util.string2MD5(loginForm.getLoginPwd()).equals(user.getLoginPwd())){
  map.put("code", UserStatusEnum.PWD_ERROR.intKey());
  map.put("msg", UserStatusEnum.PWD_ERROR.value());
  return map;
 }
 
 //根據(jù)數(shù)據(jù)庫的用戶信息查詢Token
 return operateToKen(map, user, user.getId());
 }

token操作

private Map<String, Object> operateToKen(Map<String, Object> map, UserEntity user, long userId) {
 //根據(jù)數(shù)據(jù)庫的用戶信息查詢Token
 TokenEntity token = tokenmapper.findByUserId(userId);
 //為生成Token準備
 String TokenStr = "";
 Date date = new Date();
 int nowTime = (int) (date.getTime() / 1000);
 //生成Token
 TokenStr = creatToken(userId, date);
 if (null == token) {
  //第一次登陸
  token = new TokenEntity();
  token.setToken(TokenStr);
  token.setBuildTime(nowTime);
  token.setUserId(userId);
  token.setId(Long.valueOf(IdUtils.getPrimaryKey()));
  tokenmapper.addToken(token);
 }else{
  //登陸就更新Token信息
  TokenStr = creatToken(userId, date);
  token.setToken(TokenStr);
  token.setBuildTime(nowTime);
  tokenmapper.updataToken(token);
 }
 UserQueryForm queryForm = getUserInfo(user, TokenStr);
 /* 將用戶信息存入session */
 /*SessionContext sessionContext = SessionContext.getInstance();
 HttpSession session = sessionContext.getSession();
 httpSession.setAttribute("userInfo", user);*/
 //返回Token信息給客戶端
 successful(map);
 map.put("data", queryForm);
 return map;
 }

生成token

private String creatToken(Long userId, Date date) {
 SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
 JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT") // 設(shè)置header
  .setHeaderParam("alg", "HS256").setIssuedAt(date) // 設(shè)置簽發(fā)時間
  .setExpiration(new Date(date.getTime() + 1000 * 60 * 60))
  .claim("userId",String.valueOf(userId) ) // 設(shè)置內(nèi)容
  .setIssuer("lws")// 設(shè)置簽發(fā)人
  .signWith(signatureAlgorithm, "簽名"); // 簽名,需要算法和key
 String jwt = builder.compact();
 return jwt;
 }

至此,token登錄OK

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringIOC?BeanDefinition的加載流程詳解

    SpringIOC?BeanDefinition的加載流程詳解

    這篇文章主要為大家介紹了SpringIOC?BeanDefinition的加載流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • Java構(gòu)造器使用方法及注意事項

    Java構(gòu)造器使用方法及注意事項

    這篇文章主要介紹了Java構(gòu)造器使用方法及注意事項的相關(guān)資料,這里舉例說明如何使用構(gòu)造器及需要注意的地方,需要的朋友可以參考下
    2017-07-07
  • Java編程實現(xiàn)基于用戶的協(xié)同過濾推薦算法代碼示例

    Java編程實現(xiàn)基于用戶的協(xié)同過濾推薦算法代碼示例

    這篇文章主要介紹了Java編程實現(xiàn)基于用戶的協(xié)同過濾推薦算法代碼示例,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • 區(qū)塊鏈java代碼實現(xiàn)

    區(qū)塊鏈java代碼實現(xiàn)

    這篇文章主要為大家詳細介紹了區(qū)塊鏈java代碼實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 在Mybatis中association標簽多層嵌套的問題

    在Mybatis中association標簽多層嵌套的問題

    這篇文章主要介紹了在Mybatis中association標簽多層嵌套的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Flink支持哪些數(shù)據(jù)類型?

    Flink支持哪些數(shù)據(jù)類型?

    Apache Flink 以其獨特的方式來處理數(shù)據(jù)類型以及序列化,這種方式包括它自身的類型描述符、泛型類型提取以及類型序列化框架.本文檔描述了它們背后的概念和基本原理,需要的朋友可以參考下
    2021-06-06
  • 仿京東平臺框架開發(fā)開放平臺(包含需求,服務(wù)端代碼,SDK代碼)

    仿京東平臺框架開發(fā)開放平臺(包含需求,服務(wù)端代碼,SDK代碼)

    現(xiàn)在開放平臺越來越多了,下面針對仿京東開放平臺框架,封裝自己的開放平臺,分享給大家。先感謝一下京東開放平臺的技術(shù)大佬們,下面從開放平臺需求,服務(wù)端代碼,SDK代碼三大塊進行分享
    2021-06-06
  • G1垃圾回收器在并發(fā)場景調(diào)優(yōu)詳解

    G1垃圾回收器在并發(fā)場景調(diào)優(yōu)詳解

    這篇文章主要為大家介紹了G1垃圾回收器在并發(fā)場景調(diào)優(yōu)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • Java并發(fā)線程池實例分析講解

    Java并發(fā)線程池實例分析講解

    這篇文章主要介紹了Java并發(fā)線程池實例,線程池——控制線程創(chuàng)建、釋放,并通過某種策略嘗試復用線程去執(zhí)行任務(wù)的一個管理框架,從而實現(xiàn)線程資源與任務(wù)之間一種平衡
    2023-02-02
  • IDEA 項目創(chuàng)建Mapper的xml文件的方法

    IDEA 項目創(chuàng)建Mapper的xml文件的方法

    這篇文章主要介紹了IDEA 項目創(chuàng)建Mapper的xml文件的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11

最新評論