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

vue-router結(jié)合vuex實(shí)現(xiàn)用戶(hù)權(quán)限控制功能

 更新時(shí)間:2019年11月14日 08:26:19   作者:genetalks_大數(shù)據(jù)  
這篇文章主要介紹了vue-router結(jié)合vuex實(shí)現(xiàn)用戶(hù)權(quán)限控制功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

為了實(shí)現(xiàn)前端校驗(yàn)用戶(hù),后端需要在用戶(hù)登錄的時(shí)候記錄下該用戶(hù)的狀態(tài)并加密之后返回給前端。之后該用戶(hù)的所有請(qǐng)求都應(yīng)該附帶這個(gè)加密后的狀態(tài),后端取到這個(gè)狀態(tài)解密,并與之前保存的狀態(tài)對(duì)比,以此來(lái)判斷該用戶(hù)是否登錄或合法。

我這里使用了node簡(jiǎn)單了寫(xiě)了個(gè)本地的express服務(wù),來(lái)實(shí)現(xiàn)上述功能。完整的代碼直接貼出來(lái):

// server.js
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const app = express();
// secret是后端加密的密鑰
const secret = 'rhwl';
app.use((req, res, next) => {
 res.header('Access-Control-Allow-Origin', '*');
 res.header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS,POST,PUT');
 res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
 if (req.method.toLowerCase() === 'options') {
  return res.end();
 }
 next();
});
app.use(bodyParser.json());
app.post('/login', (req, res) => {
 const { username } = req.body;
 if (username === 'admin') { // 如果是合法用戶(hù),使用jwt進(jìn)行加密生成token
  res.json({
   code: 0,
   username: 'admin',
   token: jwt.sign({ username: 'admin' }, secret, {
    expiresIn: 20,
   }),
  });
 } else {
  res.json({
   code: 1,
   data: '用戶(hù)名不存在',
  });
 }
});
app.get('/validate', (req, res) => {
 const token = req.headers.authorization; // 在請(qǐng)求頭中附帶token信息
 jwt.verify(token, secret, (err, decode) => { // 驗(yàn)證token是否合法
  if (err) {
   return res.json({
    code: 1,
    data: '當(dāng)前token無(wú)效',
   });
  }
  // 如果驗(yàn)證合法,重新生成新的token,并返回信息
  res.json({
   username: decode.username,
   code: 0,
   token: jwt.sign({ username: 'admin' }, secret, {
    expiresIn: 20,
   }),
  });
 });
});
app.listen(3000, ()=>{
  console.log('服務(wù)器在3000端口運(yùn)行');
});

2.項(xiàng)目中axios封裝

然后我們?cè)陧?xiàng)目中封裝符合自己需求的ajax請(qǐng)求,現(xiàn)在通常都是基于axios庫(kù)。在自己封裝的ajax插件中,要在每次的請(qǐng)求頭中添加上token。代碼實(shí)現(xiàn):

// ajaxResquest.js
import axios from 'axios';
class ajaxResquest {
  constructor(){
    // 根據(jù)當(dāng)前模式自動(dòng)切換baseURL
    this.baseURL = process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : '/';
    this.timeout = 5000; // 設(shè)置請(qǐng)求超時(shí)為5s
  }
  request(config){
    const instance = axios.create({
      baseURL: this.baseURL,
      timeout: this.timeout,
    });
    instance.interceptor.request.use((config) => {
      // 將保存在本地的token添加到每次請(qǐng)求的請(qǐng)求頭中
      // 這樣就可以實(shí)現(xiàn)在請(qǐng)求時(shí)順帶附加用戶(hù)的校驗(yàn)信息的需求
      config.headers.Authorization = localStorage.getItem('token');
      return config;
    }, (err) => {
      return Promise.reject(err);
    });
    instance.interceptor.response.use((req,res) => {
      return req.data;
    }, (err) => {
      Promise.reject(err);
    });
    // 將使用request時(shí)候需要的參數(shù)也添加到instance中
    return instance(config);
  }
}
export default new ajaxRequest();

然后統(tǒng)一管理項(xiàng)目api接口:

// api.js
import ajax from 'ajaxResquest';
export const userLogin = (username) => ajax.request({url: '/login', method: 'POST', data: {
  username,
}});
export const userValidate = () => ajax.request({url: '/validate'});

接下來(lái)我們?cè)陧?xiàng)目中具體實(shí)現(xiàn)用戶(hù)登陸和權(quán)限校驗(yàn)的需求。

3.vuex記錄用戶(hù)登錄

先將登陸組件配合vuex使用來(lái)觸發(fā)用戶(hù)登陸的行為,并且將用戶(hù)登錄之后的信息保存在vuex中,登陸組件的代碼:

// userLogin component
<template>
  <div>
    <el-input style="width:200px" v-model="username"></el-input>
    <el-button @click="login">登錄</el-button>
  </div>
</template>
<script>
export default {
  data(){
    return {
      username: '',
    }
  },
  methods: {
    login(){
      // 這里觸發(fā)vuex中的actions,在vuex中調(diào)用用戶(hù)登陸接口
      // 從而將用戶(hù)登陸之后的狀態(tài)保存至vuex中
      this.$store.dispatch('login', this.username).then((data) => {
        // 登陸成功之后,路由跳轉(zhuǎn)至用戶(hù)賬戶(hù)頁(yè)或者進(jìn)行你需要的操作
        this.$router.push('/profile');
      });
    }
  }
}
</script>

接著是vuex的store.js

// store.js
import Vue from 'vue';
import Vuex from 'vuex';
import {userLogin, userValidate} from 'api.js';
Vue.use(Vuex);
export default Vuex.store({
  state: {
    username: '', 
  },
  mutations: {
    setUsername(state, username){
      state.username = username;
    }
  },
  actions: {
    async login({commit}, username){
      const res = await userLogin(username);
      if (res.code === 1) { // 登錄失敗
        return Promise.reject(res);
      }
      // 登錄成功后將接口返回的token保存在本地
      localStorage.setItem('token', res.token);
      // 將用戶(hù)名保存在vuex中
      commit('setUsername', username);
    }
  }
});

經(jīng)過(guò)上面的操作,我們將用戶(hù)登錄中調(diào)用登錄接口的操作通過(guò)vuex實(shí)現(xiàn),將成功登錄后的用戶(hù)名保存在vuex中,此時(shí)的token保存在瀏覽器本地。但是vuex中的數(shù)據(jù)并不是持久數(shù)據(jù),刷新之后保存的用戶(hù)名就會(huì)消失,接下來(lái)我們實(shí)現(xiàn)刷新頁(yè)面或者路由跳轉(zhuǎn)時(shí)進(jìn)行用戶(hù)校驗(yàn),如果驗(yàn)證通過(guò)則會(huì)生成新的token和username并保存。

4.vuex配合vue-router實(shí)現(xiàn)登錄校驗(yàn)

當(dāng)用戶(hù)刷新頁(yè)面時(shí),或者點(diǎn)擊其他頁(yè)面切換路由router時(shí),需要調(diào)用后端的validate接口,該接口通過(guò)驗(yàn)證已保存的token校驗(yàn)當(dāng)前用戶(hù)是否合法。我們?cè)趘uex的store.js中添加以下代碼:

export default Vuex.store({
  state: {
    username: '',
  },
  mutations: {
    setUsername(state, username){
      state.username = username;
    } 
  },
  actions: {
    async login({commit}, username){
      ...
    },
    async validate({commit}) {
      // 調(diào)用userValidate時(shí),會(huì)將
      const res = await userValidate();
      if (res.code === 1) { // 此時(shí)用戶(hù)校驗(yàn)失敗
        return Promise.reject(res);
      }
      // 如果校驗(yàn)成功,重新保存token和username 
      localStorage.setItem('token', res.token);
      commit('setUsername', res.username);
    }
  }
});

基本上我們通過(guò)上面的代碼就實(shí)現(xiàn)了用戶(hù)權(quán)限控制所需要的所有前提操作:

  • 用戶(hù)成功登陸在本地保存token
  • 在自己封裝的ajax的請(qǐng)求頭部添加保存的token信息
  • 后端服務(wù)提供對(duì)前端token的校驗(yàn)?zāi)芰?br />

那么接下來(lái)就就是路由router刷新或改變的時(shí)候如何進(jìn)行權(quán)限控制了。

5.vue-router鉤子實(shí)現(xiàn)用戶(hù)權(quán)限控制

使用過(guò)vue-router的同學(xué)們都知道,路有也是有鉤子函數(shù)的,在官方文檔里面被稱(chēng)為 導(dǎo)航守衛(wèi) 。導(dǎo)航守衛(wèi)允許我們可以精準(zhǔn)的在每個(gè)路由變化的時(shí)候進(jìn)行操作,我們就這里判斷用戶(hù)權(quán)限。在vue項(xiàng)目的的main.js中修改:

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 在這里使用路由的導(dǎo)航守衛(wèi)進(jìn)行權(quán)限控制
// 可以自定義不需要校驗(yàn)用戶(hù)的路由白名單
const whiteList = ['/'];
router.beforeEach(async (to, from, next) => {
  // 要去的頁(yè)面是白名單,直接跳轉(zhuǎn)
  if (whiteList.includes(to.path)) {
    next();
  }
  // 不是白名單,調(diào)用vuex中的validate行為
  const flag = await store.dispatch('validate');
  if (flag) { // 用戶(hù)校驗(yàn)通過(guò),直接跳轉(zhuǎn)
    next();
  } else { // 用戶(hù)校驗(yàn)失敗
    next('/login'); // 跳轉(zhuǎn)至用戶(hù)登陸頁(yè)
    // 順帶說(shuō)一下,這里還可以在router中的meta屬性中添加isNeeded: true/false
    // 然后配合這個(gè)屬性更加精細(xì)的控制未通過(guò)用戶(hù)校驗(yàn)時(shí)的頁(yè)面是否允許跳轉(zhuǎn)
  }
});
// vuex
Vue.use(ElementUI);
Vue.config.productionTip = false;
new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app');

總結(jié)

以上所述是小編給大家介紹的vue-router結(jié)合vuex實(shí)現(xiàn)用戶(hù)權(quán)限控制,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • vue3引入Element-plus的詳細(xì)步驟記錄

    vue3引入Element-plus的詳細(xì)步驟記錄

    Element Plus是為適配Vue3而對(duì)Element UI進(jìn)行重構(gòu)后產(chǎn)生的前端組件庫(kù),包含豐富的基礎(chǔ)組件,下面這篇文章主要給大家介紹了關(guān)于vue3引入Element-plus的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • Vue在頁(yè)面右上角實(shí)現(xiàn)可懸浮/隱藏的系統(tǒng)菜單

    Vue在頁(yè)面右上角實(shí)現(xiàn)可懸浮/隱藏的系統(tǒng)菜單

    這篇文章主要介紹了Vue在頁(yè)面右上角實(shí)現(xiàn)可懸浮/隱藏的系統(tǒng)菜單,實(shí)現(xiàn)思路大概是通過(guò)props將showCancel這個(gè)Boolean值傳遞到子組件,對(duì)父子組件分別綁定事件,來(lái)控制這個(gè)系統(tǒng)菜單的顯示狀態(tài)。需要的朋友可以參考下
    2018-05-05
  • vue實(shí)現(xiàn)類(lèi)似淘寶商品評(píng)價(jià)頁(yè)面星級(jí)評(píng)價(jià)及上傳多張圖片功能

    vue實(shí)現(xiàn)類(lèi)似淘寶商品評(píng)價(jià)頁(yè)面星級(jí)評(píng)價(jià)及上傳多張圖片功能

    最近在寫(xiě)一個(gè)關(guān)于vue的商城項(xiàng)目,然后集成在移動(dòng)端中,開(kāi)發(fā)需求中有一界面,類(lèi)似淘寶商城評(píng)價(jià)界面!接下來(lái)通過(guò)本文給大家分享vue實(shí)現(xiàn)類(lèi)似淘寶商品評(píng)價(jià)頁(yè)面星級(jí)評(píng)價(jià)及上傳多張圖片功能,需要的朋友參考下吧
    2018-10-10
  • vue項(xiàng)目打包自動(dòng)更新版本號(hào)且自動(dòng)刷新緩存的方法示例

    vue項(xiàng)目打包自動(dòng)更新版本號(hào)且自動(dòng)刷新緩存的方法示例

    這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目打包自動(dòng)更新版本號(hào)且自動(dòng)刷新緩存的相關(guān)資料,文中通過(guò)代碼及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-11-11
  • vue axios同步請(qǐng)求解決方案

    vue axios同步請(qǐng)求解決方案

    這篇文章主要介紹了vue axios同步請(qǐng)求解決方案,需要的朋友可以參考下
    2017-09-09
  • Vue+Element UI 實(shí)現(xiàn)視頻上傳功能

    Vue+Element UI 實(shí)現(xiàn)視頻上傳功能

    這篇文章主要介紹了Vue+Element UI 實(shí)現(xiàn)視頻上傳功能,前臺(tái)使用Vue+Element UI中的el-upload組件實(shí)現(xiàn)視頻上傳及進(jìn)度條展示,后臺(tái)提供視頻上傳API并返回URL,具體實(shí)現(xiàn)代碼及效果展示跟隨小編一起看看吧
    2022-01-01
  • vue3頁(yè)面query參數(shù)變化并重新加載頁(yè)面數(shù)據(jù)方式

    vue3頁(yè)面query參數(shù)變化并重新加載頁(yè)面數(shù)據(jù)方式

    在Web開(kāi)發(fā)中,頁(yè)面間的跳轉(zhuǎn)及數(shù)據(jù)刷新是常見(jiàn)問(wèn)題,通過(guò)使用$router.push和$router.replace方法,可以控制頁(yè)面跳轉(zhuǎn)的行為,具體操作時(shí),若發(fā)現(xiàn)頁(yè)面ID變更后數(shù)據(jù)未刷新,可通過(guò)給router-view標(biāo)簽添加key值解決,若使用keep-alive
    2024-10-10
  • Vue中的偵聽(tīng)器及使用場(chǎng)景

    Vue中的偵聽(tīng)器及使用場(chǎng)景

    Vue中的偵聽(tīng)器是一種響應(yīng)式機(jī)制,可以對(duì)指定的數(shù)據(jù)進(jìn)行監(jiān)聽(tīng),并在數(shù)據(jù)變化時(shí)執(zhí)行相應(yīng)的回調(diào)函數(shù)。常用于監(jiān)聽(tīng)復(fù)雜數(shù)據(jù)類(lèi)型的變化,如對(duì)象和數(shù)組。通過(guò)偵聽(tīng)器,可以實(shí)現(xiàn)數(shù)據(jù)的自動(dòng)更新和邏輯處理等功能,提高代碼的可讀性和可維護(hù)性
    2023-05-05
  • vue.js表格組件開(kāi)發(fā)的實(shí)例詳解

    vue.js表格組件開(kāi)發(fā)的實(shí)例詳解

    Vue.js通過(guò)簡(jiǎn)潔的API提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng)。在前端紛繁復(fù)雜的生態(tài)中,Vue.js有幸受到一定程度的關(guān)注,所以本文將從各方面對(duì)Vue.js的組件開(kāi)發(fā)做一個(gè)深入介紹。有需要的朋友們可以參考借鑒。
    2016-10-10
  • Vue3?實(shí)現(xiàn)網(wǎng)頁(yè)背景水印功能的示例代碼

    Vue3?實(shí)現(xiàn)網(wǎng)頁(yè)背景水印功能的示例代碼

    這篇文章主要介紹了Vue3?實(shí)現(xiàn)網(wǎng)頁(yè)背景水印功能,這里水印的字體大小、顏色和排布參考了企業(yè)微信的背景水印,使得看起來(lái)不那么突兀,需要的朋友可以參考下
    2022-08-08

最新評(píng)論

郁南县| 巢湖市| 文化| 邓州市| 昌乐县| 江永县| 香河县| 呼伦贝尔市| 桦甸市| 元阳县| 黎平县| 高平市| 安宁市| 牙克石市| 邹城市| 巩义市| 五台县| 南召县| 星子县| 内黄县| 嘉禾县| 苍山县| 拉孜县| 视频| 沂南县| 松江区| 确山县| 武强县| 星座| 庆阳市| 花莲市| 珲春市| 明光市| 当阳市| 东乌珠穆沁旗| 牙克石市| 东莞市| 济宁市| 阆中市| 如东县| 夏邑县|