偽前端設(shè)想JWT構(gòu)建用戶體系【后端】

關(guān)鍵詞:刷新JWT,更新,緩存

平臺(tái):數(shù)據(jù)庫(kù)(mongodb, mysql),redis

首先在用戶注冊(cè)的時(shí)候,我們需要收集用戶的賬號(hào)信息 譬如 id + username + 亂七八糟mix salt 的組合用md5加密成一串用戶初始token,和用戶信息一起存入數(shù)據(jù)庫(kù),作為用戶在平臺(tái)唯一識(shí)別token(注意這個(gè)token和jwt發(fā)的token不是一回事)。

在用戶注冊(cè)登錄的時(shí)候就把上述token作為cookie塞給用戶瀏覽器,存在redis維護(hù)一份(這里看策略,一般可能2-4小時(shí)后失效),redis保存信息形式大概為token:{用戶基本信息}
【下面的代碼僅為思路展示,像很多sql和redis操作不能直接套用,僅供參考】

async login(ctx, next) {
?      try {
?        const {username, pwd} = await Util.treamentFormData(ctx.req)
?        const handlePsw = md5Pwd(pwd)
?        const getCheckUserInfo = await query(
?          `SELECT FROM users WHERE name = ${username} AND vkey = ${handlePsw}`
?        )
?        if (!getCheckUserInfo) {
?          return ctx.body =({code: 1, msg: '用戶名或密碼錯(cuò)誤'})
?        } else {
?          const userInfo = {username: findOneRes.username, vkey: findOneRes.vkey}
?          const token = Util.setToken(userInfo)
?          const redis = initStone() 
?          redis.set(findOneRes.vkey, JSON.stringify(userInfo) , 'EX', 60 * 60 * 2) *//秒為單位 2個(gè)小時(shí)redis失效*
?          const CookieOpt = CookieConfig()
?          try {
?            ctx.cookies.set('_token', findOneRes.vkey, CookieOpt)
?          } catch(err) {
?            console.log(err)
?          }
?          ctx.response.body = ({code: 0, data: {...findOneRes._doc, token}})
?        }
?      } catch (e) {
?        ctx.response.body = e
?      }
  },

基于jwt有時(shí)效性我們前端調(diào)用的時(shí)候先查驗(yàn)一下jwt的有效時(shí)間,這里可以發(fā)起一個(gè)請(qǐng)求去獲取最新的jwt,使用cookie作為憑據(jù)(所以這個(gè)cookie的時(shí)間可以設(shè)長(zhǎng)一點(diǎn),比如一個(gè)月),然后使用全局變量維護(hù)這個(gè)拿下來(lái)的jwt,當(dāng)下一個(gè)接口請(qǐng)求的時(shí)候,會(huì)先去本地拿這個(gè)對(duì)象看看過(guò)沒(méi)過(guò)期,如果過(guò)期了,去調(diào)這個(gè)獲取jwt的接口再拿一次新的,這個(gè)接口返回新的token和用戶個(gè)人信息

  *// 處理鑒權(quán) 不刷新cookie*
  async accessToken(ctx, next) {
?    try {
?        const getCookie = ctx.request.header.cookie
?       if (getCookie) {
?          *// redis.set('DD', 100, 'EX', 5) //秒為單位*
?          const parseCookie = Util.handleCookie(getCookie)
?          const getCookieToken = parseCookie['_token']
?          const redis = initStone() 
?          const result = await redis.get(`${getCookieToken}`)
?          if (result) {
?            const userInfo = JSON.parse(result)
?            const newToken = Util.setToken(userInfo)
?            ctx.body = ({code: 0, msg: 'success' , data: {token: newToken, userInfo}})
?          } else {
?            const getUserInfo = await query(
?              `SELECT FROM users WHERE vkey = ${handlePsw}`
?            ) 
?            if (getUserInfo) {
?              redis.set(getUserInfo.vkey, JSON.stringify(getUserInfo) , 'EX', 60 * 60 * 2) *//秒為單位 2個(gè)小時(shí)redis失效*
?              const newToken = Util.setToken(getUserInfo)
?              ctx.body = ({code: 0, msg: 'success' , data: {token: newToken, getUserInfo}})
?            } 
?          }
?       } else {
?          ctx.status = 401
?          ctx.body = ({code: -1, msg: 'fail'})
?       }
?    }  catch(e) {
?       console.log(e)
?    }
  }

這里通過(guò)cookie的toke去獲取用戶信息,如果redis上有這個(gè)信息(即_token = redis上的key "_token"),直接使用redis上的信息頒布新的jwt,如果沒(méi)有,則通過(guò)這個(gè)token我們可以去查詢數(shù)據(jù)里面?zhèn)€人信息,查到后再塞一次到redis,并且再返回個(gè)人信息和新的jwt給前端。

{
?   account: {
?       username: '',
                token: ''
?       …otherInfo,
?   }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容