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

Spring下token過(guò)期時(shí)間分平臺(tái)(web和app)設(shè)置方法

 更新時(shí)間:2024年10月21日 10:57:12   作者:星月夢(mèng)瑾  
本文詳細(xì)介紹了在Spring環(huán)境下,針對(duì)web端和APP端實(shí)現(xiàn)不同token過(guò)期時(shí)間的方法,通過(guò)整合SpringBoot、springSecurity和JWT框架,文章講解了登錄流程、JWT的基本組成以及token鑒權(quán)的核心步驟,需要的朋友可以參考下

前言

 本文介紹了Spring下的登錄和鑒權(quán)機(jī)制的主要方法以及 token認(rèn)證的主要流程,并介紹在spring中web端和APP端設(shè)置不同token過(guò)期時(shí)間的實(shí)現(xiàn)方法。主要基于SpringBoot+springSecurity+JWT框架實(shí)現(xiàn)。

一、應(yīng)用場(chǎng)景

同一系統(tǒng)的跨平臺(tái)操作,基于用戶習(xí)慣,web端和app端用戶使用時(shí)間長(zhǎng)短常常不同,統(tǒng)一過(guò)長(zhǎng)時(shí)間容易造成服務(wù)器資源浪費(fèi),統(tǒng)一過(guò)短使得用戶未操作完就登錄過(guò)期。因此,為更便于用戶使用,分平臺(tái)設(shè)置token過(guò)期時(shí)間能提升用戶體驗(yàn)。

二、登錄方法和token鑒權(quán)

要分平臺(tái)設(shè)置token過(guò)期時(shí)間,首先要了解SpringSecurity登錄流程的主要方法和token生成。

1、登錄流程

登錄-->校驗(yàn)用戶名、密碼、驗(yàn)證碼-->redis存儲(chǔ)登錄用戶信息-->生成token(JWT)-->返回token

//  僅展示關(guān)鍵語(yǔ)句

@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
    AjaxResult ajax = AjaxResult.success();
    // 生成令牌
    String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
            loginBody.getUuid(),loginBody.getClientPubKey(), loginBody.getPlatForm());
    ajax.put(Constants.TOKEN, token);
    return ajax;
}
public String login(String username, String aes_password, String code, String uuid, String clientPubKey, String platForm) {
// 驗(yàn)證用戶名密碼
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
// 生成token
loginUser.setPlatForm(platForm);
return tokenService.createToken(loginUser);
}

2、JWT

JWT是一種基于 Token 的認(rèn)證授權(quán)機(jī)制, 可用于創(chuàng)建token。

Token = Head+info+sign

Head: 編碼方式

Info:用戶信息,包括用戶名等自定義信息

Sign:簽名

如下所示:

Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_USER_KEY, token);
claims.put(Constants.JWT_USERID, loginUser.getUserId());
claims.put(Constants.JWT_USERNAME, loginUser.getUsername());

private String createToken(Map<String, Object> claims)
{
    String token = Jwts.builder()
            .setClaims(claims)
            .signWith(SignatureAlgorithm.HS512, secret).compact();
    return token;
}

3、Token鑒權(quán)

登錄后返回的token存于前端緩存,每次請(qǐng)求時(shí)放于請(qǐng)求頭,經(jīng)過(guò)攔截器時(shí)解析token,并verifyToken方法校驗(yàn)token是否有效或過(guò)期,同時(shí)redreshToken延長(zhǎng)過(guò)期時(shí)間(本次為活躍)。

// 校驗(yàn)

public void verifyToken(LoginUser loginUser)
{
    long expireTime = loginUser.getExpireTime();
    long currentTime = System.currentTimeMillis();

    if(loginUser.getPlatForm().equals("pc")){
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN_PC)
        {
            refreshToken(loginUser);
        }

    }else if(loginUser.getPlatForm().equals("app")) {
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN_APP) {
            refreshToken(loginUser);
        }
    }
}

// 更新過(guò)期時(shí)間

public void refreshToken(LoginUser loginUser)
{
    if(loginUser.getPlatForm().equals("pc")){
        expireTime = pcExpireTime;
    }else if(loginUser.getPlatForm().equals("app")){
        expireTime = appExpireTime;
    }
    loginUser.setLoginTime(System.currentTimeMillis());
    loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
    // 根據(jù)uuid將loginUser緩存
    String userKey = getTokenKey(loginUser.getToken());
    redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
}

三、實(shí)現(xiàn)方法

1、配置文件

Pc端過(guò)期時(shí)間59min,app端3天

# token配置
token:
  # 令牌自定義標(biāo)識(shí)
  header: Authorization
  # 令牌密鑰
  secret: abcdefghijklmnopqrstuvwxyz
  # 令牌有效期(默認(rèn)59分鐘; APP端3天)
  expireTime:
    defaultExpireTime: 59
    pcExpireTime: 59
    appExpireTime: 4320

2、登錄信息實(shí)體類

增加平臺(tái)信息

src/main/java/com/common/core/domain/model/LoginBody.java

src/main/java/com/common/core/domain/model/LoginUser.java

public class LoginBody {

//  ****其他省略

/**
 * 登錄平臺(tái): 手機(jī)端='app',PC端='pc'
 */
private String platForm;
public String getPlatForm() {
    return platForm;
}
public void setPlatForm(String platForm) {
    this.platForm = platForm;
}

}

3、登錄方法

(1)login的controller層方法

生成token的方法參數(shù)加上平臺(tái)信息

src/main/java/com/web/controller/system/SysLoginController.java

@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
    AjaxResult ajax = AjaxResult.success();
    // 生成令牌
    String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
            loginBody.getUuid(),loginBody.getClientPubKey(), loginBody.getPlatForm());
    ajax.put(Constants.TOKEN, token);
    return ajax;
}

(2)登錄信息檢驗(yàn)及token生成

src/main/java/com/inspur/framework/web/service/SysLoginService.java

// 基于SpringSecurity的驗(yàn)證方法,修改返回的登錄用戶信息,可以在返回后再人工設(shè)置。

public String login(String username, String aes_password, String code, String uuid, String clientPubKey, String platForm) {

// 僅僅展示重要關(guān)鍵語(yǔ)句

// 驗(yàn)證用戶名密碼

authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));

// 返回登錄信息

LoginUser loginUser = (LoginUser) authentication.getPrincipal();

// 生成token
loginUser.setPlatForm(platForm);
return tokenService.createToken(loginUser);
}
private String createToken(Map<String, Object> claims)
{
    String token = Jwts.builder()
            .setClaims(claims)
            .signWith(SignatureAlgorithm.HS512, secret).compact();
    return token;
}

(3)Token驗(yàn)證鑒權(quán)及更新

src/main/java/com/inspur/common/service/TokenService.java

//  用戶每次請(qǐng)求將token信息存放于請(qǐng)求頭,經(jīng)過(guò)攔截器攔截。

@Component
public class TokenService
{

// 令牌有效期(默認(rèn)30分鐘)

@Value("${token.expireTime.defaultExpireTime}")
private int expireTime;

@Value("${token.expireTime.pcExpireTime}")
private int pcExpireTime;
@Value("${token.expireTime.appExpireTime}")
private int appExpireTime;


//pc端-距離20分鐘時(shí)刷新token過(guò)期時(shí)間
private static final Long MILLIS_MINUTE_TEN_PC = 20 * 60 * 1000L;
//app端-距離1天時(shí)刷新token過(guò)期時(shí)間
private static final Long MILLIS_MINUTE_TEN_APP = 24 * 60 * 60 * 1000L;

public void verifyToken(LoginUser loginUser)
{
    long expireTime = loginUser.getExpireTime();
    long currentTime = System.currentTimeMillis();

    if(loginUser.getPlatForm().equals("pc")){
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN_PC)
        {
            refreshToken(loginUser);
        }
    }else if(loginUser.getPlatForm().equals("app")) {
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN_APP) {
            refreshToken(loginUser);
        }
    }
}
public void refreshToken(LoginUser loginUser)
{
    if(loginUser.getPlatForm().equals("pc")){
        expireTime = pcExpireTime;
    }else if(loginUser.getPlatForm().equals("app")){
        expireTime = appExpireTime;
    }

    loginUser.setLoginTime(System.currentTimeMillis());
    loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
    // 根據(jù)uuid將loginUser緩存
    String userKey = getTokenKey(loginUser.getToken());
    redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
}

}

4、前端傳遞平臺(tái)信息

(1)web端(基于Vue)

登錄傳遞平臺(tái)信息:platForm=‘pc’

src/store/modules/user.js

// 登錄
Login({commit}, userInfo) {
  const username = userInfo.username.trim()
  const password = userInfo.password
  const code = userInfo.code
  const uuid = userInfo.uuid
  const platForm = 'pc'
  return new Promise((resolve, reject) => {
    getPublicKey(username).then(res => {
      if (res.code === 200) {
        let result = encryptData(res.data, password);
        let aes_password = result.encryptedData;
        login(username, aes_password, code, uuid,result.clientKey,platForm).then(res => {
          setToken(res.token)
          commit('SET_TOKEN', res.token)
          resolve()
        }).catch(error => {
          reject(error)
        })
      }
    })
  })
},

src/api/login.js

export function login(username, password, code, uuid,clientPubKey) {
  const platForm = 'pc'
  const data = {
    username,
    password,
    code,
    uuid,
    clientPubKey,
    platForm
  }
  return request({
    url: '/login',
    method: 'post',
    data: data
  })
}

(2)app端(基于uniapp)

api/login.js

// 登錄方法
export function login(username, password, code, uuid) {
  let platForm = 'app'
  const data = {
    username,
    password,
    code,
    uuid,
    platForm
  }
  return request({
    'url': '/appLogin',
    headers: {
      isToken: false
    },
    'method': 'post',
    'data': data
  })
}

總結(jié) 

到此這篇關(guān)于Spring下token過(guò)期時(shí)間分平臺(tái)(web和app)設(shè)置的文章就介紹到這了,更多相關(guān)token過(guò)期時(shí)間分平臺(tái)設(shè)置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java編程環(huán)境搭建和變量基本使用圖文教程

    Java編程環(huán)境搭建和變量基本使用圖文教程

    這篇文章主要介紹了Java編程環(huán)境搭建和變量基本使用,結(jié)合圖文形式詳細(xì)分析了java編程語(yǔ)言環(huán)境搭建、配置、變量、注釋的基本使用方法,需要的朋友可以參考下
    2020-02-02
  • SpringBoot報(bào)錯(cuò)Invalid?bound?statement?(not?found)問(wèn)題排查和解決方案

    SpringBoot報(bào)錯(cuò)Invalid?bound?statement?(not?found)問(wèn)題排查和解決方案

    這篇文章主要介紹了SpringBoot報(bào)錯(cuò)Invalid?bound?statement?(not?found)問(wèn)題排查和解決方案,文中通過(guò)圖文結(jié)合的方式講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • Volatile關(guān)鍵字的使用案例

    Volatile關(guān)鍵字的使用案例

    這篇文章主要介紹了Volatile關(guān)鍵字的作用,Volatile關(guān)鍵字的作用主要有兩個(gè),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java?SSM框架講解

    Java?SSM框架講解

    這篇文章主要介紹了什么是SSM框架,SSM框架是spring、spring?MVC?、和mybatis框架的整合,是標(biāo)準(zhǔn)的MVC模式。想進(jìn)一步了解的同學(xué)可以詳細(xì)參考本文
    2023-03-03
  • 解讀spring.factories文件配置詳情

    解讀spring.factories文件配置詳情

    這篇文章主要介紹了解讀spring.factories文件配置詳情,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Java自定義異常與異常使用的最佳方式

    Java自定義異常與異常使用的最佳方式

    這篇文章主要介紹了Java自定義異常與異常使用的最佳方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中for循環(huán)的執(zhí)行過(guò)程分析

    Java中for循環(huán)的執(zhí)行過(guò)程分析

    這篇文章主要介紹了Java中for循環(huán)的執(zhí)行過(guò)程,實(shí)例分析了for循環(huán)的執(zhí)行原理與順序,對(duì)于深入理解Java具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • SpringBoot3.2新特性之JdbcClient的使用

    SpringBoot3.2新特性之JdbcClient的使用

    本文主要介紹了SpringBoot3.2新特性之JdbcClient的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-08-08
  • 如何在maven本地倉(cāng)庫(kù)中添加oracle的jdbc驅(qū)動(dòng)

    如何在maven本地倉(cāng)庫(kù)中添加oracle的jdbc驅(qū)動(dòng)

    文章介紹了在Maven項(xiàng)目中添加Oracle數(shù)據(jù)庫(kù)驅(qū)動(dòng)ojdbc5時(shí)遇到的問(wèn)題以及解決問(wèn)題的兩種方法,方法一為簡(jiǎn)單粗暴,但沒(méi)有體現(xiàn)Maven倉(cāng)庫(kù)的作用,需要手動(dòng)管理jar包,方法二為在Maven本地倉(cāng)庫(kù)中添加Oracle的JDBC驅(qū)動(dòng),過(guò)程較為繁瑣,但配置一次后可以多次使用
    2024-11-11
  • 解決redisTemplate向redis中插入String類型數(shù)據(jù)時(shí)出現(xiàn)亂碼問(wèn)題

    解決redisTemplate向redis中插入String類型數(shù)據(jù)時(shí)出現(xiàn)亂碼問(wèn)題

    這篇文章主要介紹了解決redisTemplate向redis中插入String類型數(shù)據(jù)時(shí)出現(xiàn)亂碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論

顺义区| 象山县| 西平县| 沈阳市| 台东市| 津市市| 边坝县| 方正县| 汶上县| 扎囊县| 紫阳县| 中卫市| 临夏市| 新邵县| 伊金霍洛旗| 阜平县| 黔西| 息烽县| 洛扎县| 正安县| 博爱县| 彰化县| 鹤山市| 保定市| 阿坝县| 桑植县| 印江| 兴山县| 湟源县| 敦化市| 石家庄市| 鄯善县| 揭阳市| 蓝田县| 泰兴市| 龙门县| 连州市| 蓬安县| 开化县| 阳江市| 贵阳市|