0
点赞
收藏
分享

微信扫一扫

前端工作小结6-vue处理token

小布_cvg 2022-10-19 阅读 235

最开始后端来和我说 token 时候,
虽然装着很懂的样子,但当时我听的是一脸懵逼
之前学习的时候,根本没接触过token,
后来查了一些资料,终于明白了token 的原理,以及应用。

token 原理

token 的意思是 令牌, 就像是我们登陆某个账号时,会向你的安全令发送验证一样。

前端工作小结6-vue处理token_ajax


一个道理, 在前端处理登陆时,并非简单的验证账号密码是否正确, 而是发送给后台。

后台验证成功后, 会发送给我们一个 token。

token 大概长这样:

​​​27d2da79303d4abaa271e71c2d6f3b48.d86c828583c5c6160e8acfee88ba1590​​

在我们登陆成功之后,后台会返回给我们token ,之后的每一次请求, 都要先验证token。

就是说,我们要将token 放到请求里。 token正确,才能执行下一步操作。
总而言之,使用token 会很安全。

处理 token

token 的处理思路很简单:
1.把冰箱门打开
2.向后台发送登陆请求,
3.接收到后台传来的 token
4.将 token 储存起来,
5.将 token 放到请求的 header 里
6.关上冰箱门

我这里储存 token 选择的是放到本地的​​Session Storage​​ 里面,也用到了 vuex

vuex 需要提前配置好, 我这里使用的是单文件配置

前端工作小结6-vue处理token_拦截器_02

下载什么的就略过了…

还有 store/index.js 的文件配置


1. ​​import Vue from 'vue'​​
2. ​​import Vuex from 'vuex'​​
3.
4. ​​Vue.use(Vuex)​​
5.
6. ​​export default new Vuex.Store({​​
7. ​​state: {​​
8. ​​token: ''​​
9. ​​},​​
10. ​​mutations: {​​
11. ​​set_token (state, token) {​​
12. ​​state.token = token​​
13. ​​sessionStorage.token = token​​
14. ​​},​​
15. ​​del_token (state) {​​
16. ​​state.token = ''​​
17. ​​sessionStorage.removeItem('token')​​
18. ​​}​​
19. ​​}​​
20. ​​})​​

这里在 ​​mutation​​ 里设置了两个方法 set :设置 和 del :删除 两个方法。

具体操作

首先在登陆界面写一个有关登陆的函数,在其中发送ajax 请求,这里用的是 axios。

    1. ​​login () {​​
    2. ​​this.$axios({​​
    3. ​​method: 'post',​​
    4. ​​url: '/api/v1/teacher/login',​​
    5. ​​params: {​​
    6. ​​'t_num': this.t_num,​​
    7. ​​'t_pwd': this.t_pwd​​
    8. ​​}​​
    9. ​​}).then(res => {​​
    10. ​​console.log(res)​​
    11. ​​let data = 'brear ' + res.data.access_token​​
    12. ​​this.$store.commit('set_token', data)​​
    13. ​​if (store.state.token) {​​
    14. ​​this.$router.push('/home')​​
    15. ​​console.log(store.state.token)​​
    16. ​​} else {​​
    17. ​​this.$router.replace('/login')​​
    18. ​​}​​
    19. ​​}).catch(err => {​​
    20. ​​console.log(err)​​
    21. ​​})​​
    22. ​​}​​

    在这里要注意的是后台与我约定好了 ,在每次发送请求时,在token前面加一个 字符串和一个空格。
    所以是这样 ​​​let data = 'brear ' + res.data.access_token​​ 总之具体的需求 还是根据实际情况而定,这里只是储存token,以及登陆成功跳转到主页

    还要注意的是我们这里用到的是 access_token ,有关 access_token 和 refresh_token ,有兴趣的同学 可以去百度一下。

    这里成功获取到了token,但是之前提到过,我们每次发送请求时,都需要验证 token,
    这就需要把 token 放到 header 里,就需要配置 ajax 拦截器。

    还是axios…

    我这里直接在 main.js 文件里配置


    1. ​​axios.defaults.headers.common['authorization'] = store.state.token​​
    2.
    3. ​​axios.interceptors.request.use(config => {​​
    4. ​​if (store.state.token) {​​
    5. ​​config.headers.common['authorization'] = store.state.token​​
    6. ​​}​​
    7. ​​return config​​
    8. ​​},​​
    9. ​​error => {​​
    10. ​​return Promise.reject(error)​​
    11. ​​})​​
    12.
    13. ​​axios.interceptors.response.use(​​
    14. ​​response => {​​
    15. ​​return response​​
    16. ​​},​​
    17. ​​error => {​​
    18. ​​if (error.response) {​​
    19. ​​switch (error.response.status) {​​
    20. ​​case 401:​​
    21. ​​this.$store.commit('del_token')​​
    22. ​​router.replace({​​
    23. ​​path: '/login',​​
    24. ​​query: {​​
    25. ​​redirect: router.currentRoute.fullPath​​
    26. ​​}​​
    27. ​​})​​
    28. ​​}​​
    29. ​​}​​
    30. ​​return Promise.reject(error.response.data)​​
    31. ​​}​​
    32. ​​)​​

    这里用到的是 ajax 拦截器
    在发送请求之前 先将 token 放到 header 里面 ,
    如 

    ​​​axios.defaults.headers.common['authorization'] = store.state.token​​

    还需要处理两个情况,
    1.token 不存在,跳转到登陆页,重新获取 token
    2.token 过期 ,如 error 返回 401 也是跳转到登录页, 重新获取token

    关于路由 router

    配置 token 时还需要判定跳转页面时 token 的授权。

    还是直接上代码

      1. ​​router.beforeEach((to, from, next) => {​​
      2. ​​if (to.matched.some(r => r.meta.requireAuth)) {​​
      3. ​​if (store.state.token) {​​
      4. ​​next()​​
      5. ​​} else {​​
      6. ​​next({​​
      7. ​​path: '/login',​​
      8. ​​query: {​​
      9. ​​redirect: to.fullPath​​
      10. ​​}​​
      11. ​​})​​
      12. ​​}​​
      13. ​​} else {​​
      14. ​​next()​​
      15. ​​}​​
      16. ​​})​​
      同样是在 main.js 中配置,当

      然还要安装vue-router …

      同样是单文件

      前端工作小结6-vue处理token_拦截器_03


      这里的 router/index.js 就不仔细说了…

      重要的是配置


      1. ​​if (sessionStorage.getItem('token')) {​​
      2. ​​store.commit('set_token', sessionStorage.getItem('token'))​​
      3. ​​}​​

      这个写到 router/index.js 文件中,

      在 main.js 里 :
      引入 router…

      import router from './router'

      在每次跳转页面之前 判断是否需要登陆 后查看


      1. ​​router.beforeEach((to, from, next) => {​​
      2. ​​if (to.matched.some(r => r.meta.requireAuth)) {​​
      3. ​​if (store.state.token) {​​
      4. ​​next()​​
      5. ​​} else {​​
      6. ​​next({​​
      7. ​​path: '/login',​​
      8. ​​query: {​​
      9. ​​redirect: to.fullPath​​
      10. ​​}​​
      11. ​​})​​
      12. ​​}​​
      13. ​​} else {​​
      14. ​​next()​​
      15. ​​}​​
      16. ​​})​​

      这里的

      ​​​if (to.matched.some(r => r.meta.requireAuth))​​

      需要在router/index 中配置:

      1. ​​{​​
      2. ​​path: '/paper',​​
      3. ​​name: 'Paper',​​
      4. ​​component: Paper,​​
      5. ​​meta: {​​
      6. ​​requireAuth: true​​
      7. ​​}​​
      8. ​​}​​

      就是在需要 登陆 才能操作的页面里加入 meta

      判断是否需要登陆

      最后附上 main.js 的所有代码

        1. ​​// The Vue build version to load with the `import` command​​
        2. ​​// (runtime-only or standalone) has been set in webpack.base.conf with an alias.​​
        3. ​​import Vue from 'vue'​​
        4. ​​import Vuex from 'vuex'​​
        5. ​​import App from './App'​​
        6. ​​import router from './router'​​
        7. ​​import store from './store/index'​​
        8. ​​import axios from 'axios'​​
        9.
        10. ​​Vue.prototype.$axios = axios​​
        11. ​​Vue.use(Vuex)​​
        12. ​​Vue.config.productionTip = false​​
        13. ​​axios.defaults.headers.common['Content-type'] = 'application/json'​​
        14. ​​axios.defaults.headers.common['authorization'] = store.state.token​​
        15.
        16. ​​axios.interceptors.request.use(config => {​​
        17. ​​if (store.state.token) {​​
        18. ​​config.headers.common['authorization'] = store.state.token​​
        19. ​​}​​
        20. ​​return config​​
        21. ​​},​​
        22. ​​error => {​​
        23. ​​return Promise.reject(error)​​
        24. ​​})​​
        25.
        26. ​​axios.interceptors.response.use(​​
        27. ​​response => {​​
        28. ​​return response​​
        29. ​​},​​
        30. ​​error => {​​
        31. ​​if (error.response) {​​
        32. ​​switch (error.response.status) {​​
        33. ​​case 401:​​
        34. ​​this.$store.commit('del_token')​​
        35. ​​router.replace({​​
        36. ​​path: '/login',​​
        37. ​​query: {​​
        38. ​​redirect: router.currentRoute.fullPath​​
        39. ​​}​​
        40. ​​})​​
        41. ​​}​​
        42. ​​}​​
        43. ​​return Promise.reject(error.response.data)​​
        44. ​​}​​
        45. ​​)​​
        46. ​​router.beforeEach((to, from, next) => {​​
        47. ​​if (to.matched.some(r => r.meta.requireAuth)) {​​
        48. ​​if (store.state.token) {​​
        49. ​​next()​​
        50. ​​} else {​​
        51. ​​next({​​
        52. ​​path: '/login',​​
        53. ​​query: {​​
        54. ​​redirect: to.fullPath​​
        55. ​​}​​
        56. ​​})​​
        57. ​​}​​
        58. ​​} else {​​
        59. ​​next()​​
        60. ​​}​​
        61. ​​})​​
        62.
        63. ​​/* eslint-disable no-new */​​
        64. ​​new Vue({​​
        65. ​​el: '#app',​​
        66. ​​router,​​
        67. ​​store,​​
        68. ​​components: { App },​​
        69. ​​template: '<App/>'​​
        70. ​​})​​



        举报

        相关推荐

        0 条评论