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

Vue axios獲取token臨時(shí)令牌封裝案例

 更新時(shí)間:2020年09月11日 14:46:21   作者:longlongValue  
這篇文章主要介紹了Vue axios獲取token臨時(shí)令牌封裝案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧

前言

為什么非要寫這個(gè)博客呢?因?yàn)檫@件事讓我有一種蛋蛋的優(yōu)疼。剩下的都別問,反正問我也不會說。因?yàn)榱鞒虉D我都不想(懶得)畫。

開發(fā)架構(gòu)

前端頁面:Vue

網(wǎng)絡(luò)請求:Axios;方式:vue add axios

緩存方案

全局變量:Vuex

本地緩存:LocalStorage

技術(shù)依賴

你猜?

背景

公司開發(fā)一個(gè)嵌入App的Web頁面,安全方面使用老套路:App通過URL傳參給前端(包含簽名),前端把參數(shù)透傳給H5后端驗(yàn)簽,完事兒之后前端再?zèng)Q定用戶是否合法。另外定義了N個(gè)JS方法前端根據(jù)固定GET參數(shù)判斷是安卓還是蘋果來調(diào)用。

初步設(shè)想

關(guān)于token設(shè)計(jì)方案的初步設(shè)想是這樣的:第一次進(jìn)入的時(shí)候獲取token,后端檢查簽名是否通過。不通過則彈框請從合法途徑進(jìn)入頁面并且不消失。

否則就可以讓用戶繼續(xù)后續(xù)操作,直到后端返回token過期特定狀態(tài)碼回來前端在用戶無感的情況下調(diào)用JS方法重新獲取URL參數(shù)請求token,完事兒之后繼續(xù)用戶的請求操作。(為避免用戶使用舊token在其他地方操作數(shù)據(jù),每次獲取token都重新從App中獲取并驗(yàn)證,而不是在接口中刷新并返回新的token)

蛋疼事項(xiàng)

一期的時(shí)候定義URL參數(shù)時(shí)沒有版本控制,導(dǎo)致二期新增JS方法迭代版本時(shí)前端新增頁面調(diào)用了未知方法頁面毫無反應(yīng);埋點(diǎn)數(shù)據(jù)也不知道是幾期的…

為盡量避免請求過程中出現(xiàn)token過期導(dǎo)致的1次請求變3次請求現(xiàn)象每次調(diào)用請求之前需要先檢查token時(shí)效的異步方法(如果token過期則調(diào)用getToken獲取新的token并存儲在本地)導(dǎo)致block嵌套。

后面又封裝了N個(gè)方法就不說了…

升級設(shè)想

版本什么的這個(gè)先不說,就這個(gè)token問題我總不能每次新增一個(gè)請求就復(fù)制粘貼復(fù)制粘貼的吧?能煩死人!那我只能在axios請求之前判斷token時(shí)效性啦。

直奔主題

函數(shù)聲明

getToken:從本地取已存儲token

checkToken:檢查token時(shí)效,失效調(diào)用refreshToken函數(shù)成功則存儲本地,否則返回錯(cuò)誤原因

refreshToken:調(diào)用JS方法從App獲取簽名參數(shù)重新請求token

注意事項(xiàng)

在checkToken過程中token過期時(shí),先移除本地已過期token緩存數(shù)據(jù)。

/* eslint-disable no-console */
/* eslint-disable no-unused-vars */
"use strict";

import Vue from 'vue';
import axios from "axios";
import { getToken } from '../utils/storage.js'
import { checkToken, refreshToken, clearCache } from "../utils/utils.js";

// Full config: https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.headers.post["Content-Type"] = "application/json";

let cancel,
 promiseArr = {};
let config = {
 baseURL: process.env.VUE_APP_BASE_URL,
 timeout: 8 * 1000, // Timeout
 withCredentials: true, // Check cross-site Access-Control
};

const _axios = axios.create(config);

_axios.interceptors.request.use(
 function (config) {
  // Do something before request is sent
  let token = getToken();
  // alert("token1:" + token);
  //發(fā)起請求時(shí),取消掉當(dāng)前正在進(jìn)行的相同請求
  if (promiseArr[config.url]) {
   promiseArr[config.url]("請稍后");
   promiseArr[config.url] = cancel;
  } else {
   promiseArr[config.url] = cancel;
  }
  if (token) {
   return checkToken(null)
     .then((result) => {
      // console.log("refreshToken result:", result);
      if (result === true) {
       token = getToken()
       // alert("token2:" + token);
       config.headers.common["authorization"] = token;
       return config;
      } else {
       return Promise.reject(Error(result))
      }
     }).catch((err) => {
      // 終止這個(gè)請求
      return Promise.reject(err);
     });
  }
  return config;
 },
 function (error) {
  // Do something with request error
  return Promise.reject(error);
 }
);

// Add a response interceptor
_axios.interceptors.response.use(
 function (response) {
  // Do something with response data
  let { status, statusText, data } = response;
  if (err_check(status, statusText, data) && data) {
   // var randomColor = `rgba(${parseInt(Math.random() * 255)},${parseInt(
   //  Math.random() * 255
   // )},${parseInt(Math.random() * 255)})`;

   // console.log(
   //  "%c┍------------------------------------------------------------------┑",
   //  `color:${randomColor};`
   // );
   // console.log("| 請求地址:", response.config.url);
   // console.log("| 請求參數(shù):", response.config.data);
   // console.log("| 返回?cái)?shù)據(jù):", response.data);
   // console.log(
   //  "%c┕------------------------------------------------------------------┙",
   //  `color:${randomColor};`
   // );
   if (data.resCode === "0001") {
    clearCache()
    var config = response.config;
    var url = config.url;
    url = url.replace("/apis", "").replace(process.env.VUE_APP_BASE_URL, "")
    config.url = url;
    // alert(JSON.stringify(config))
    return refreshToken(null)
     .then((result) => {
      // console.log("refreshToken result:", result);
      if (result == true) {
       let token = getToken()
       if (token) {
        config.headers["authorization"] = token;
       }
       return axios(config)
        .then((result) => {
        let { status, statusText, data } = result;
        // console.log('接口二次請求 result:', result);
        if (err_check(status, statusText, data) && data) {
         return Promise.resolve(data)
        } else {
         return Promise.reject(Error(data.resDesc));
        }
       }).catch((err) => {
        // console.log('接口二次請求 err:' + err);
        return Promise.reject(err);
       });
      } else {
       // alert("result:" + result)
       return Promise.reject(Error(data.resDesc))
      }
     }).catch((err) => {
      // 終止這個(gè)請求
      // alert("終止這個(gè)請求:" + err.message)
      // console.log("refreshToken err:", err);
      return Promise.reject(err);
     });
   } else {
    return Promise.resolve(data);
   }
  } else {
   return Promise.reject(Error(statusText));
  }
  // return response;
 },
 function (error) {
  // Do something with response error
  // console.log("error", error);
  return Promise.reject(error);
 }
);

// eslint-disable-next-line no-unused-vars
const err_check = (code, message, data) => {
 if (code == 200) {
  return true;
 }
 return false;
};

Plugin.install = function (Vue, options) {
 Vue.axios = _axios;
 window.axios = _axios;
 Object.defineProperties(Vue.prototype, {
  axios: {
   get() {
    return _axios;
   }
  },
  $axios: {
   get() {
    return _axios;
   }
  },
 });
};

Vue.use(Plugin)
export default Plugin;

補(bǔ)充知識:vue+ axios+token 封裝axios 封裝接口url,帶token請求,token失效刷新

一、封裝axios

import axios from 'axios'
import qs from "qs" 
const TIME_OUT_MS = 60 * 1000 // 默認(rèn)請求超時(shí)時(shí)間
//axios.defaults.baseURL = 'http://localhost:8080'; 
 
// http request 攔截器
axios.interceptors.request.use(
  config => {
    if ($cookies.get("access_token")) { // 判斷是否存在token,如果存在的話,則每個(gè)http header都加上token
      config.headers.Authorization ='Bearer '+ $cookies.get("access_token");
    }
    return config;
  },
  err => {
    return Promise.reject(err);
}); 
 
// http response 攔截器
axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    console.log("response error :"+error);
    if (error.response) {
      switch (error.response.status) {
        case 401:
          console.log("token 過期");
          var config = error.config;
          refresh(config);
          return;
      }
    }
    return Promise.reject(error)  // 返回接口返回的錯(cuò)誤信息
  });
/*
*刷新token
*/
function refresh(config){
  var refreshToken = $cookies.get("refresh_token");
  var grant_type = "refresh_token";
  axios({
    method: 'post',
    url: '/oauth/token',
    data: handleParams({"grant_type":grant_type,"refresh_token":refreshToken}),
    timeout: TIME_OUT_MS,
    headers: {}
  }).then(
    (result) => {
      if(result.data.access_token){  //重新保存token
        $cookies.set("access_token",result.data.access_token);
        $cookies.set("refresh_token",result.data.refresh_token);
        //需要重新執(zhí)行
        axios(config);
      }else{ 
 
        //this.$events.emit('goto', 'login');
        window.location.reload();
      }
    }
  ).catch((error) => {
    //this.$events.emit('goto','login');
    window.location.reload();
  });
}
/*
* @param response 返回?cái)?shù)據(jù)列表
*/
function handleResults (response) { 
 
  var result = {
    success: false,
    message: '',
    status: [],
    errorCode: '',
    data: {}
  }
  if (response.status == '200') {
    result.status = response.status;
    result.data = response.data;
    result.success = true;
  }
  return result
} 
 
// function handleUrl (url) {
//   //url = BASE_URL + url
//   url =root +url;
// // BASE_URL是接口的ip前綴,比如http:10.100.1.1:8989/
//   return url
// } 
 
/*
* @param data 參數(shù)列表
* @return
*/
function handleParams (data) {
  return qs.stringify(data);
} 
export default {
  /*
   * @param url
   * @param data
   * @param response 請求成功時(shí)的回調(diào)函數(shù)
   * @param exception 異常的回調(diào)函數(shù)
   */
  post (url, data, response, exception) {
    axios({
      method: 'post',
      //url: handleUrl(url),
      url: url,
      data: handleParams(data),
      timeout: TIME_OUT_MS,
      headers: {
        //'Content-Type': 'application/json; charset=UTF-8'
      }
    }).then(
      (result) => {
        response(handleResults(result))
      }
    ).catch(
      (error) => {
        if (exception) {
          exception(error)
        } else {
          console.log(error)
        }
      }
    )
  },
  /*
   * get 請求
   * @param url
   * @param response 請求成功時(shí)的回調(diào)函數(shù)
   * @param exception 異常的回調(diào)函數(shù)
   */
  get (url,data, response, exception) {
    axios({
      method: 'get',
      url: url,
      params:data,
      timeout: TIME_OUT_MS,
      headers: {
        'Content-Type': 'application/json; charset=UTF-8'
      }
    }).then(
      (result) => {
        response(handleResults(result))
      }
    ).catch(
      (error) => {
        console.log("error"+response);
        if (exception) {
          exception(error)
        } else {
          console.log(error)
        }
      }
    )
  }
}

二、配置axios 跨域,以及請求baseUrl

1.config-->index.js

'
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation. 
 
const path = require('path') 
 
//引入跨域配置
var proxyConfig = require('./proxyConfig') 
module.exports = {
  dev: { 
 
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    //proxyTable: {}, //默認(rèn)跨域配置為空
    proxyTable: proxyConfig.proxy, 
 
    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8886, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 
 
    /**
     * Source Maps
     */ 
 
    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map', 
 
    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true, 
 
    cssSourceMap: true
  },
  
  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),
 
 
    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    // 項(xiàng)目名字改變時(shí)這里需要變化 原先為assetsPublicPath: '.'
    assetsPublicPath: './', 
 
    /**
     * Source Maps
     */ 
 
    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map', 
 
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
 
 
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}
  

2.config目錄下創(chuàng)建一個(gè)文件 proxyConfig.js文件

module.exports={
  proxy:{
    '/':{ //將localhost:8081 映射為 /apis
      target:'http://localhost:8080',//接口地址
      changeOrigin: true,// 如果接口跨域,需要進(jìn)行這個(gè)參數(shù)配置
      secure:false, //如果接口是HTTPS接口,需要設(shè)置成true
      pathRewrite:{
        '^/':''
      }
    }
  }
}

三、封裝API 請求Url port.js

export default {
  oauth: {
    login: '/oauth/token', // 登錄
    logout: '/oauth/logout' // // 退出
  },
  user: {
    addUser: '/user/add',
    updateUser: '/user/update',
    getUser:'/user/', //+ Id
    exists:'/exists/', // +id
    enable:'/enable/', // +id
    disable:'/disable/', // +id
    delete:'/delete/',  //+id
    password:'/password ',
    query:'/query'
  }
}

四、main.js 引入

import http from './plugins/http.js'
import ports from './plugins/ports'
Vue.prototype.http = http
Vue.prototype.ports = ports

五、使用

login.vue中使用

login() {
  this.http.post(this.ports.oauth.login,{username:this.userId,
    password:this.password,grant_type:'password'}, res => {
    if (res.success) {
    // 返回正確的處理
    頁面跳轉(zhuǎn)
    this.$events.emit('goto', 'edit');
  } else {
    // 返回錯(cuò)誤的處理
    //alert("等待處理");
  }
},err =>{
    //console.log("正在處理"+err.response.status);
    if(err.response.status=='400'){
      //顯示用戶名或密碼錯(cuò)誤
      this.$refs.username.focus();
      this.$refs.hint.click();
    }
  })
   
}

以上這篇Vue axios獲取token臨時(shí)令牌封裝案例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示隱藏

    vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示隱藏

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示隱藏,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Vue 中的compile操作方法

    Vue 中的compile操作方法

    這篇文章主要介紹了Vue 中的compile操作方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2018-02-02
  • Vux+Axios攔截器增加loading的問題及實(shí)現(xiàn)方法

    Vux+Axios攔截器增加loading的問題及實(shí)現(xiàn)方法

    這篇文章主要介紹了Vux+Axios攔截器增加loading的問題及實(shí)現(xiàn)方法,文中通過實(shí)例代碼介紹了vue中使用axios的相關(guān)知識,需要的朋友可以參考下
    2018-11-11
  • vue2?對全局自定義指令一次性進(jìn)行注冊的方法

    vue2?對全局自定義指令一次性進(jìn)行注冊的方法

    這篇文章主要介紹了vue2?對全局自定義指令一次性進(jìn)行注冊,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Vue.js實(shí)現(xiàn)的計(jì)算器功能完整示例

    Vue.js實(shí)現(xiàn)的計(jì)算器功能完整示例

    這篇文章主要介紹了Vue.js實(shí)現(xiàn)的計(jì)算器功能,結(jié)合完整實(shí)例形式分析了vue.js響應(yīng)鼠標(biāo)事件實(shí)現(xiàn)基本的數(shù)值運(yùn)算相關(guān)操作技巧,可實(shí)現(xiàn)四則運(yùn)算及乘方、開方等功能,需要的朋友可以參考下
    2018-07-07
  • 基于Vue3實(shí)現(xiàn)日歷組件的示例代碼

    基于Vue3實(shí)現(xiàn)日歷組件的示例代碼

    日歷在很多地方都可以使用的到,這篇文章主要介紹了如何利用vue3實(shí)現(xiàn)簡單的日歷控件,文中通過示例代碼講解詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 深入理解Vuex的作用

    深入理解Vuex的作用

    這篇文章主要介紹了深入理解Vuex的作用,對Vuex感興趣的同學(xué),可以參考下
    2021-05-05
  • 一文搞懂Vue3中toRef和toRefs的區(qū)別

    一文搞懂Vue3中toRef和toRefs的區(qū)別

    toRef 和 toRefs都是Vue3 中的響應(yīng)式轉(zhuǎn)換工具函數(shù),換句話說,toRef 和 toRefs 就是用來創(chuàng)建響應(yīng)式的引用的,主要用來取出響應(yīng)式對象里的屬性,或者解構(gòu)響應(yīng)式對象,本文小編就來帶大家搞清楚Vue3中toRef和toRefs的區(qū)別,需要的朋友可以參考下
    2023-09-09
  • vue 查看dist文件里的結(jié)構(gòu)(多種方式)

    vue 查看dist文件里的結(jié)構(gòu)(多種方式)

    本文通過三種方式給大家介紹了vue 查看dist文件里的結(jié)構(gòu),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01
  • vue實(shí)現(xiàn)用戶登錄切換

    vue實(shí)現(xiàn)用戶登錄切換

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)用戶登錄切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04

最新評論