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

Vuex處理用戶Token過期及優(yōu)化設(shè)置封裝本地存儲操作模塊

 更新時間:2022年09月01日 11:06:55   作者:下周六  
這篇文章主要為大家介紹了Vuex處理用戶Token優(yōu)化設(shè)置封裝本地存儲操作模塊及Token?過期問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1. 處理用戶 Token

Token 是用戶登錄成功之后服務(wù)端返回的一個身份令牌,在項(xiàng)目中的多個業(yè)務(wù)中需要使用到:

  • 訪問需要授權(quán)的 API 接口
  • 校驗(yàn)頁面的訪問權(quán)限
  • ...

問題:Token往哪兒存?

我們只有在第一次用戶登錄成功之后才能拿到 Token。所以為了能在其它模塊中獲取到 Token 數(shù)據(jù),我們需要把它存儲到一個公共的位置,方便隨時取用。

本地存儲

  • 獲取麻煩
  • 數(shù)據(jù)不是響應(yīng)式

Vuex 容器(推薦)

  • 獲取方便
  • 響應(yīng)式的

使用容器存儲 Token 的思路:

登錄成功,將 Token 存儲到 Vuex 容器中

  • 獲取方便
  • 響應(yīng)式

為了持久化,還需要把 Token 放到本地存儲

  • 持久化

總結(jié): Vuex狀態(tài)管理工具可有可無 (*?ω-q)

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  // 1. 存儲數(shù)據(jù)的地方 - 類比于vue文件的data()
  state: {
    // 一個對象,儲存當(dāng)前登錄用戶的token數(shù)據(jù)
    user: {}
  },
  // 2. 外界修改store中state的屬性值,必須通過mutations中設(shè)置的修改方法 - 類比methods
  // 注意:這里方法里面的代碼和.vue文件中的書寫方式有差異,注意區(qū)分
  mutations: {
    setUser (state, data) {
      state.user = data
    }
  },
  // 3. 涉及到異步操作后修改state數(shù)據(jù)時,必須先過actions中的自定義方法,通過actions去調(diào)用mutations中的方法
  actions: {
  },
  // 4. 是state中數(shù)據(jù)的計算屬性 - 類比computed
  getters: {
  },
  // 5. 模塊化vuex,可以讓每一個模塊擁有自己的 state、mutation、action、 getters,使得結(jié)構(gòu)非常清晰,方便管理。
  modules: {
  }
})

登錄成功以后將后端返回的 token 調(diào)用commit方法存到store中

async onSubmit () {
	...
  try {
    const res = await loginAPI(user)
    console.log('登錄成功', res)
    // 調(diào)用store中的方法,將接口返回的token存到狀態(tài)管理器中
    this.$store.commit('setUser', res.data.data)
    // 提示 success 或者 fail 的時候,會先把其它的 toast 先清除
    this.$toast.success('登錄成功')
  } catch (err) {
    ...
},

3. 將 store中的 token 相關(guān)數(shù)據(jù)存儲到容器中

const TOKEN_KEY = 'TOUTIAO_USER'
export default new Vuex.Store({
  state: {
    user: JSON.parse(window.localStorage.getItem(TOKEN_KEY))
  },
  mutations: {
    setUser (state, data) {
      state.user = data
      // 為了防止刷新丟失,需要把數(shù)據(jù)備份到本地存儲
      window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user))
    }
  },
	...
})

2. 優(yōu)化封裝本地存儲操作模塊 - 封裝localStrage功能

創(chuàng)建 src/utils/storage.js 模塊

  • 存儲
  • 獲取
  • 刪除
// 封裝本地存儲操作模塊
/* 一個本地存儲的數(shù)據(jù)應(yīng)該擁有那些特性: 增刪改查 */
/*
  儲存數(shù)據(jù) (新增, 修改)
*/
export const setItem = (key, value) => {
  // 將數(shù)組,對象等引用數(shù)據(jù)類型轉(zhuǎn)化為JSON字符串進(jìn)行存儲
  // 將簡單數(shù)據(jù)類型直接存儲
  // 需要外界使用該方法時傳入對一個的 鍵名
  if (typeof value === 'object') {
    // 將數(shù)組,對象等引用數(shù)據(jù)類型轉(zhuǎn)化為JSON字符串進(jìn)行存儲
    value = JSON.stringify(value)
  }
  window.localStorage.setItem(key, value)
}
/*
  獲取數(shù)據(jù)
*/
export const getItem = key => {
  // 如果該鍵存儲的是引用數(shù)據(jù)類型的JSON字符串,那么需要進(jìn)行JSON.parse的轉(zhuǎn)化
  const data = window.localStorage.getItem(key)
  // 使用JSON.parse()做JSON數(shù)據(jù)轉(zhuǎn)化時可能會出現(xiàn)報錯
  // 1. 做條件判斷(要去找到所有滿足、不滿足的條件) 2. 做錯誤判斷
  try {
    // 先嘗試做JSON.parse()的轉(zhuǎn)化,如果報錯了,在把他當(dāng)成原始數(shù)據(jù)進(jìn)行返回
    return JSON.parse(data)
  } catch (error) {
    return data
  }
}
/*
  刪除緩存數(shù)據(jù)
*/
export const removeItem = key => {
  window.localStorage.removeItem(key)
}

在store/index.js引入方法

import { getItem, setItem } from '../utils/storage.js'

使用方法

import { getItem, setItem } from '../utils/storage.js'
const TOKEN_KEY = 'TOUTIAO_USER'
export default new Vuex.Store({
  state: {
    user:getItem(TOKEN_KEY)
  },
  mutations: {
    setUser (state, data) {
      state.user = data
      // 為了防止刷新丟失,需要把數(shù)據(jù)備份到本地存儲
      setItem(TOKEN_KEY, state.user)
    }
  },
	...
})

3. Vuex各屬性的使用

創(chuàng)建測試用store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  // state存放狀態(tài),
  state: {
    name: 'tom', // 需要共用的數(shù)據(jù)
    age: '22'
  },
  // getter為state的計算屬性
  getters: {
    getName: (state) => state.name, // 獲取name
    getAge: (state) => state.age
  },
  // mutations可更改狀態(tài)的邏輯,同步操作
  mutations: {
    setName: (state, data) => { state.name = data },
    setAge: (state, data) => { state.age = data }
  },
  // 提交mutation,異步操作
  actions: {
    acSetName (context, name) {
      setTimeout(() => {
        // 延時1秒提交至mutations中的方法
        context.commit('setName', name)
      }, 1000)
    },
    acSetAge (context, age) {
      setTimeout(() => {
        context.commit('setAge', age)
      }, 1000)
    }
  },
  // 將store模塊化
  modules: {
  }
})

創(chuàng)建頁面comOne.vue測試計算屬性

<template>
  <div class="wrapper">
    asd
    <!-- 讀取mapGetters中的getName與getAge -->
    <div>
      name:<span>{{ getName }}</span>
    </div>
    <div>
      age:<span>{{ getAge }}</span>
    </div>
  </div>
</template>
<script>
import { mapState, mapGetters } from 'vuex' // 導(dǎo)入vuex的輔助函數(shù)
export default {
  components: {},
  // 計算屬性computed無法傳遞參數(shù)
  computed: {
    // 映射 state 中的數(shù)據(jù)為計算屬性
    ...mapState(['name', 'age']),
    // 映射 getters 中的數(shù)據(jù)為計算屬性
    ...mapGetters(['getName', 'getAge'])
  }
}
</script>
<style scoped>
</style>

創(chuàng)建comTwo.vue測試同步異步方法

<template>
  <div class="wrapper">
    <div>
      <span>同步修改:</span>
      <!--直接回車調(diào)用mapMutations中的setName方法與setAge方法-->
      <input
        v-model="nameInp"
        @keydown.enter="setName(nameInp)"
        placeholder="同步修改name"
      />
      <input
        v-model="ageInp"
        @keydown.enter="setAge(ageInp)"
        placeholder="同步修改age"
      />
    </div>
    <div>
      <span>異步修改:</span>
      <!--直接回車調(diào)用mapAtions中的acSetName方法與acSetAge方法-->
      <input
        v-model="acNameInp"
        @keydown.enter="acSetName(acNameInp)"
        placeholder="異步修改name"
      />
      <input
        v-model="AcAgeInp"
        @keydown.enter="acSetAge(AcAgeInp)"
        placeholder="異步修改age"
      />
    </div>
  </div>
</template>
<script>
import { mapMutations, mapActions } from 'vuex' // 導(dǎo)入vuex的輔助函數(shù)
export default {
  components: {},
  data () {
    return {
      nameInp: '', // 綁定輸入框的值
      ageInp: '',
      acNameInp: '',
      AcAgeInp: ''
    }
  },
  methods: {
    // 用于生成與 mutations 對話的方法,即:包含 $store.commit(xx) 的函數(shù)
    ...mapMutations(['setName', 'setAge']),
    // 用于生成與 actions 對話的方法,即:包含 $store.dispatch(xx) 的函數(shù)
    ...mapActions(['acSetName', 'acSetAge'])
  }
}
</script>
<style scoped>
</style>

4. 關(guān)于 Token 過期問題

登錄成功之后后端會返回兩個 Token:

  • token:訪問令牌,有效期2小時
  • refresh_token:刷新令牌,有效期14天,用于訪問令牌過期之后重新獲取新的訪問令牌

我們的項(xiàng)目接口中設(shè)定的 Token 有效期是 2 小時,超過有效期服務(wù)端會返回 401 表示 Token 無效或過期了。

為什么過期時間這么短?

  • 為了安全,例如 Token 被別人盜用

過期了怎么辦?

  • 讓用戶重新登錄,用戶體驗(yàn)太差了
  • 使用 refresh_token 解決 token 過期

如何使用 refresh_token 解決 token 過期?

到課程的后面我們開發(fā)的業(yè)務(wù)功能豐富起來之后,再給大家講解 Token 過期處理。

大家需要注意的是在學(xué)習(xí)測試的時候如果收到 401 響應(yīng)碼,請重新登錄

5.優(yōu)化設(shè)置 Token

項(xiàng)目中的接口除了登錄之外大多數(shù)都需要提供 token 才有訪問權(quán)限。

通過接口文檔可以看到,后端接口要求我們將 token 放到請求頭 Header 中并以下面的格式發(fā)送。

字段名稱:Authorization

字段值:Bearer token,注意 Bearertoken 之間有一個空格

方式一:在每次請求的時候手動添加(麻煩)。

axios({
  method: "",
  url: "",
  headers: {
    Authorization: "Bearer token"
  }
})

方式二:使用請求攔截器統(tǒng)一添加(推薦,更方便)。

src/utils/request.js 中添加攔截器統(tǒng)一設(shè)置 token:

import axios from 'axios'
import store from '../store/index.js'

const request = axios.create({
  baseURL: 'http://toutiao.itheima.net/' // 接口的基準(zhǔn)路徑
})

// 請求攔截器
// Add a request interceptor
request.interceptors.request.use(function (config) {
  // Do something before request is sent
  // config :本次請求的配置對象
  // config 里面有一個屬性:headers
  const { user } = store.state
  if (user && user.token) {
    config.headers.Authorization = `Bearer ${user.token}`
  }
  return config
}, function (error) {
  // 如果請求出錯 - 拋出異常
  // Do something with request error
  return Promise.reject(error)
})

api.user.js注釋掉store和獲取用戶信息攜帶的請求頭

import request from '@/utils/request'
// import store from '@/store'

/**
 * 獲取用戶自己的信息
 */
export const getUserInfo = () => {
  return request({
    method: 'GET',
    url: '/v1_0/user'
    // 發(fā)送請求頭數(shù)據(jù)
    // headers: {
    //   // 注意:該接口需要授權(quán)才能訪問
    //   //       token的數(shù)據(jù)格式:Bearer token數(shù)據(jù),注意 Bearer 后面有個空格
    //   Authorization: `Bearer ${store.state.user.token}`
    // }
  })
}

以上就是Vuex處理用戶Token優(yōu)化設(shè)置封裝本地存儲操作模塊的詳細(xì)內(nèi)容,更多關(guān)于Vuex處理用戶Token的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue3的動態(tài)組件是如何工作的

    vue3的動態(tài)組件是如何工作的

    這篇文章主要介紹了vue3的動態(tài)組件是如何工作的,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-03-03
  • Vue 可拖拽組件Vue Smooth DnD的使用詳解

    Vue 可拖拽組件Vue Smooth DnD的使用詳解

    最近需要有個拖拽列表的需求,發(fā)現(xiàn)一個簡單好用的 Vue 可拖拽組件,本文主要介紹了可拖拽組件Vue Smooth DnD的使用,感興趣的可以了解一下
    2021-07-07
  • 關(guān)于Vue3中defineProps用法圖文詳解

    關(guān)于Vue3中defineProps用法圖文詳解

    在vue3中組件傳參有很多種方式,和v2大差不差,但是有的地方還是有很多的區(qū)別,下面這篇文章主要給大家介紹了關(guān)于Vue3中defineProps用法的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • Vue實(shí)現(xiàn)二維碼的展示及下載功能

    Vue實(shí)現(xiàn)二維碼的展示及下載功能

    這篇文章主要介紹了Vue實(shí)現(xiàn)二維碼的展示及下載功能,其中downloadQRCode()函數(shù)中的url為要下載的文件的路徑,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • 基于el-table實(shí)現(xiàn)行內(nèi)增刪改功能

    基于el-table實(shí)現(xiàn)行內(nèi)增刪改功能

    這篇文章主要介紹了基于el-table實(shí)現(xiàn)行內(nèi)增刪改功能,用過通過操作按鈕點(diǎn)擊刪除或者編輯功能即可實(shí)現(xiàn)相應(yīng)的效果,下面小編給大家分享實(shí)例代碼感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • vue實(shí)現(xiàn)右鍵點(diǎn)擊彈框信息功能

    vue實(shí)現(xiàn)右鍵點(diǎn)擊彈框信息功能

    這篇文章主要介紹了vue實(shí)現(xiàn)右鍵點(diǎn)擊彈框信息功能方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • VUE實(shí)現(xiàn)圖片驗(yàn)證碼功能

    VUE實(shí)現(xiàn)圖片驗(yàn)證碼功能

    這篇文章主要為大家詳細(xì)介紹了VUE實(shí)現(xiàn)圖片驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 在vue中使用v-bind:class的選項(xiàng)卡方法

    在vue中使用v-bind:class的選項(xiàng)卡方法

    今天小編就為大家分享一篇在vue中使用v-bind:class的選項(xiàng)卡方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue3.0 vue-router4.0打包后頁面空白的解決方法

    vue3.0 vue-router4.0打包后頁面空白的解決方法

    本文主要介紹了vue3.0 vue-router4.0打包后頁面空白的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • VUE3使用JSON編輯器的詳細(xì)圖文教程

    VUE3使用JSON編輯器的詳細(xì)圖文教程

    最近項(xiàng)目中有用到j(luò)son編輯器,我選用了這款vue的編輯器,看起來也是比較簡潔,接下來就具體介紹一下它,下面這篇文章主要給大家介紹了關(guān)于VUE3使用JSON編輯器的詳細(xì)圖文教程,需要的朋友可以參考下
    2023-04-04

最新評論

临猗县| 九寨沟县| 志丹县| 林州市| 新乡县| 长岛县| 崇礼县| 涿鹿县| 成安县| 卫辉市| 兴化市| 榆树市| 井陉县| 张家川| 平顶山市| 林西县| 鄂尔多斯市| 永兴县| 铜山县| 天峨县| 陇南市| 威信县| 新宾| 保亭| 保康县| 绥阳县| 南召县| 高青县| 邵阳县| 北辰区| 攀枝花市| 洪雅县| 丘北县| 三明市| 岑溪市| 山东省| 修水县| 临洮县| 乐昌市| 永川市| 百色市|