zoukankan      html  css  js  c++  java
  • axios 拦截 , 页面跳转, token 验证(自己摸索了一天搞出来的)

    最近做项目,需要登录拦截,验证。于是使用了axios的拦截器(也是第一次使用,摸索了1天,终于搞出来了,真是太高兴啦!!!),废话不多说,直接上代码,

    项目结构:vue-cli + webpack + vue + vue-router + vuex

    项目结构截图:

    其中src下store文件夹中有两个文件,store.js和type.js,其中store.js为:

     1 /**
     2  * Created by yuwenjing on 17/9/13.
     3  */
     4 import Vuex from 'vuex'
     5 import Vue from 'vue'
     6 import * as types from './types'
     7 
     8 Vue.use(Vuex);
     9 export default new Vuex.Store({
    10     state: {
    11         token: null,
    12         userName: ''
    13     },
    14     mutations: {
    15         [types.LOGIN]: (state, data) => {
    16             localStorage.token = data;
    17             state.token = data;
    18         },
    19         [types.LOGOUT]: (state) => {
    20             localStorage.removeItem('token');
    21             state.token = null
    22         },
    23         [types.USERNAME]: (state, data) => {
    24             localStorage.userName = data;
    25             state.userName = data;
    26         }
    27     }
    28 })
    View Code

    types.js为:

     1 /**
     2  * Created by yuwenjing on 17/9/13.
     3  * vuex types
     4  */
     5 
     6 export const LOGIN = 'login';
     7 
     8 export const LOGOUT = 'logout';
     9 
    10 export const USERNAME = 'userName'
    View Code

    主要业务代码结构:

     其中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 App from './App'
     5 import store from './store/store'
     6 import * as types from './store/types'
     7 import router from './router'
     8 import axios from 'axios'
     9 
    10 Vue.config.productionTip = false
    11 //创建axios实例
    12 var $http = axios.create({});
    13 
    14 // http request 拦截器
    15 $http.interceptors.request.use(
    16   config => {
    17     if(config.url.indexOf('loginCheck')>=0){
    18       return config;
    19     }else{
    20       if (store.state.token) {
    21         config.headers.authorization = store.state.token;
    22       }
    23       return config;
    24     }
    25 
    26   },
    27   err => {
    28     return Promise.reject(err);
    29   });
    30 
    31 // http response 拦截器
    32 $http.interceptors.response.use(
    33   response => {
    34     return response;
    35   },
    36   error => {
    37     if (error.response) {
    38       switch (error.response.data.message) {
    39         case "false":
    40           // 清除token信息并跳转到登录页面
    41           store.commit(types.LOGOUT);
    42           router.replace({
    43             path: '/'
    44           })
    45       }
    46     }
    47     // console.log(JSON.stringify(error));//console : Error: Request failed with status code 402
    48     return Promise.reject(error.response.data)
    49   });
    50 
    51 Vue.prototype.$http = $http
    52 
    53 /* eslint-disable no-new */
    54 new Vue({
    55   el: '#app',
    56   store,
    57   router,
    58   $http,
    59   template: '<App/>',
    60   components: { App }
    61 })
    View Code

    router文件夹下index.js为:

     1 import Vue from 'vue'
     2 import Router from 'vue-router'
     3 import login from '@/components/login'
     4 import homePage from '@/components/homePage'
     5 import store from '../store/store'
     6 import * as types from '../store/types'
     7 
     8 Vue.use(Router)
     9 
    10 const routes = [
    11   {
    12     path:'/',
    13     component:login
    14   },
    15   {
    16     path: '/homePage',
    17     meta: {
    18       requireAuth: true,
    19     },
    20     component: homePage
    21   }
    22 ];
    23 
    24 // 页面刷新时,重新赋值token,用户名也在界面上展示
    25 if (window.localStorage.getItem('token')) {
    26   store.commit(types.LOGIN, window.localStorage.getItem('token'));
    27 }
    28 if(window.localStorage.getItem('userName')){
    29   store.commit(types.USERNAME, window.localStorage.getItem('userName'));
    30 }
    31 
    32 const router = new Router({
    33   routes
    34 });
    35 
    36 router.beforeEach((to, from, next) => {
    37   if (to.matched.some(r => r.meta.requireAuth)) {
    38     if (store.state.token) {
    39       next();
    40     }
    41     else {
    42       next({
    43         path: '/'
    44       })
    45     }
    46   }
    47   else {
    48     next();
    49   }
    50 })
    51 
    52 export default router;
    View Code

    登录界面login.vue代码为:

      1 <template>
      2   <div class="login-wrapper">
      3     <!--顶部-->
      4     <div class="top">
      5       <span class="content">
      6         <img src="../../static/img/login_logo.png" class="system-logo">
      7         <span class="system-name">北京热力面积投停管理系统</span>
      8       </span>
      9     </div>
     10     <!--顶部结束-->
     11 
     12     <!--中部-->
     13     <div class="center">
     14       <div class="login">
     15 
     16         <!--中部左侧-->
     17         <div class="left">
     18           <img src="../../static/img/login_city.png">
     19         </div>
     20         <!--中部左侧结束-->
     21 
     22         <!--中部右侧-->
     23         <div class="right">
     24 
     25 
     26           <span class="login-title">用户登录</span>
     27 
     28           <!--用户名输入-->
     29           <div class="username-wrapper">
     30             <i class="username-logo"></i>
     31             <input type="text" class="username" placeholder="用户名" v-model="username" ref="username" @focus="usernameFocus" :class="{'username-focus': isUsernameFocus}">
     32           </div>
     33           <!--用户名输入结束-->
     34 
     35           <!--密码输入-->
     36           <div class="pwd-wrapper">
     37             <i class="pwd-logo"></i>
     38             <input type="password" class="pwd" placeholder="密码" v-model="pwd" ref="pwd" @focus="pwdFocus" :class="{'pwd-focus': isPwdFocus}">
     39           </div>
     40           <!--密码输入结束-->
     41 
     42           <!--提交按钮-->
     43           <button class="login-btn" @click="clickLoginBtn">登录</button>
     44           <!--提交按钮结束-->
     45         </div>
     46         <!--中部右侧结束-->
     47       </div>
     48     </div>
     49     <!--中部结束-->
     50 
     51     <!--底部-->
     52     <div class="bottom"></div>
     53     <!--底部结束-->
     54 
     55   </div>
     56 </template>
     57 
     58 <script type="text/ecmascript-6">
     59   import * as types from '../store/types'
     60   import {SWAGGER_CONFIG} from '../config/config'
     61   export default {
     62     data() {
     63       return {
     64         // 用户名密码
     65         username: '',
     66         pwd: '',
     67         isUsernameFocus: true,
     68         isPwdFocus: false
     69       }
     70     },
     71 
     72     methods: {
     73       // 点击登录按钮
     74       clickLoginBtn() {
     75         if (this.username && this.pwd) {
     76           this.requestLoginInterface();
     77         } else {
     78           alert('用户名或密码不能为空');
     79         }
     80       },
     81 
     82       // 请求登录接口数据
     83       requestLoginInterface () {
     84         var self = this;
     85         self.$http.post(SWAGGER_CONFIG+'/Ddaas/userrole/loginCheck',
     86           {
     87             "userName":self.username,
     88             "passWord":self.pwd
     89           }
     90         ).then(function (response) {
     91           if(response.data.data == false){
     92             alert("用户名或密码不匹配!")
     93             return;
     94           }else{
     95             self.$store.commit(types.USERNAME,self.username);
     96             self.$store.commit(types.LOGIN, response.data.data);
     97             self.$router.push({path:"/homePage"});
     98           }
     99         })
    100           .catch(function (error) {
    101             console.log(error);
    102           });
    103       },
    104 
    105       usernameFocus () {
    106         this.isUsernameFocus = true;
    107         this.isPwdFocus = false;
    108       },
    109 
    110       pwdFocus() {
    111         this.isUsernameFocus = false;
    112         this.isPwdFocus = true;
    113       }
    114     },
    115 
    116     mounted () {
    117       // 挂在成功就聚焦输入框
    118       this.$refs.username.focus();
    119     }
    120   }
    121 
    122 </script>
    123 
    124 <style scoped>
    125   .login-wrapper {
    126      100%;
    127     height: 100%;
    128     min- 700px;
    129     min-height: 750px;
    130   }
    131 
    132   .login-wrapper .top {
    133      100%;
    134     height: 22%;
    135     display: flex;
    136     align-items: center;
    137   }
    138 
    139   .login-wrapper .top .content {
    140     display: block;
    141      100%;
    142     height: 61px;
    143     text-align: center;
    144   }
    145 
    146   .login-wrapper .top .content .system-logo {
    147     vertical-align: top;
    148   }
    149 
    150   .login-wrapper .top .content .system-name {
    151     font-size: 30px;
    152     line-height: 61px;
    153     color: #077fb7
    154   }
    155 
    156   .center {
    157      100%;
    158     height: 56%;
    159     background: linear-gradient(to bottom, #057fbf, #1697d4);
    160     /*text-align: center;*/
    161     display: flex;
    162     justify-content: center;
    163     align-items: center;
    164   }
    165 
    166   .center .login {
    167      52%;
    168     height: 68%;
    169     background-color: white;
    170     border-radius: 5px;
    171     border: 15px solid white;
    172     box-shadow: 0 0 0 7px rgba(139, 208, 255, 0.5);
    173   }
    174 
    175   .center .login .left {
    176      60%;
    177     height: 100%;
    178     box-sizing: border-box;
    179     float: left;
    180   }
    181 
    182   .center .login .right {
    183     float: right;
    184      40%;
    185     height: 100%;
    186     padding: 22px 8px 30px 22px;
    187   }
    188 
    189   .center .login .right .login-title {
    190     display: block;
    191      100%;
    192     height: 24px;
    193     font-size: 24px;
    194     text-align: center;
    195     line-height: 24px;
    196     vertical-align: middle;
    197   }
    198 
    199   .center .login .right .username-wrapper {
    200     position: relative;
    201   }
    202 
    203   .center .login .right .username-logo {
    204     display: inline-block;
    205     position: absolute;
    206     top: 12px;
    207     left: 10px;
    208      14px;
    209     height: 14px;
    210     background: url('../../static/img/login_user.png') no-repeat;
    211   }
    212 
    213   .center .login .right .username {
    214     display: block;
    215      100%;
    216     height: 40px;
    217     margin-top: 25px;
    218     outline: none;
    219     padding-left: 34px;
    220     border: 1px solid #e2e7eb;
    221     color: #404040;
    222   }
    223 
    224   .center .login .right .username-focus {
    225     display: block;
    226      100%;
    227     height: 40px;
    228     margin-top: 25px;
    229     outline: none;
    230     padding-left: 34px;
    231     border: 1px solid #0782bb;
    232     color: #404040;
    233   }
    234 
    235   .center .login .right .username::-webkit-input-placeholder {
    236     color: #d2d2d2;
    237   }
    238 
    239   .center .login .right .username:-moz-placeholder {
    240     color: #d2d2d2;
    241   }
    242 
    243   .center .login .right .username:-ms-input-placeholder {
    244     color: #d2d2d2;
    245   }
    246 
    247   .center .login .right .pwd-wrapper {
    248     position: relative;
    249   }
    250 
    251   .center .login .right .pwd-logo {
    252     display: inline-block;
    253     position: absolute;
    254     top: 12px;
    255     left: 10px;
    256      14px;
    257     height: 15px;
    258     background: url('../../static/img/login_pwd.png') no-repeat;
    259   }
    260 
    261   .center .login .right .pwd {
    262     display: block;
    263      100%;
    264     height: 40px;
    265     margin-top: 25px;
    266     outline: none;
    267     padding-left: 34px;
    268     border: 1px solid #e2e7eb;
    269     color: #404040;
    270   }
    271 
    272   .center .login .right .pwd-focus {
    273     display: block;
    274      100%;
    275     height: 40px;
    276     margin-top: 25px;
    277     outline: none;
    278     padding-left: 34px;
    279     border: 1px solid #0782bb;
    280     color: #404040;
    281   }
    282 
    283   .center .login .right .pwd::-webkit-input-placeholder {
    284     color: #d2d2d2;
    285   }
    286 
    287   .center .login .right .pwd:-moz-placeholder {
    288     color: #d2d2d2;
    289   }
    290 
    291   .center .login .right .pwd:-ms-input-placeholder {
    292     color: #d2d2d2;
    293   }
    294 
    295   .center .login .right .login-btn {
    296     display: block;
    297      100%;
    298     height: 40px;
    299     margin-top: 30px;
    300     background: linear-gradient(to bottom, #1799d6, #047db5);
    301     border: none;
    302     color: white;
    303     font-size: 20px;
    304     outline: none;
    305   }
    306 
    307   .center .login .left img {
    308      100%;
    309     height: 100%;
    310   }
    311 
    312   .bottom {
    313      100%;
    314     height: 22%;
    315   }
    316 </style>
    View Code

    展示用户名和注销功能都在headTop.vue中,headTop.vue为:

      1 <template>
      2     <div id="all">
      3       <div class="top-left">
      4         <p>
      5           <img src="../../../static/img/BJRLLOGO.png">
      6           <span>北京热力面积投停管理系统</span>
      7         </p>
      8       </div>
      9       <div class="top-right">
     10 
     11           <div>
     12             <ul class="first-ul">
     13               <li class="first-li">
     14                 <img src="../../../static/img/index.png" class="base-img">
     15                 <span class="nav-span">首页</span>
     16               </li>
     17               <li class="dropdown">
     18                 <img src="../../../static/img/user.png">
     19                 <span class="dropdown-toggle nav-span" data-toggle="dropdown">
     20                   {{userName}}
     21                   <!--<b class="caret"></b>-->
     22                   <img src="../../../static/img/userxiala.png">
     23                 </span>
     24                 <ul class="dropdown-menu">
     25                   <li>
     26                     <img src="../../../static/img/qiehuan.png">
     27                     <span>切换账号</span>
     28                   </li>
     29                   <li>
     30                     <img src="../../../static/img/xiugai.png">
     31                     <span>修改密码</span>
     32                   </li>
     33 
     34                   <li>
     35                     <img src="../../../static/img/tuichu.png">
     36                     <span @click="logout">退出登录</span>
     37                   </li>
     38 
     39                 </ul>
     40               </li>
     41             </ul>
     42           </div>
     43 
     44 
     45       </div>
     46 
     47     </div>
     48 </template>
     49 <style scoped>
     50   #all{
     51     100%;
     52     height:100%;
     53     background: #0A86C0;
     54   }
     55   .top-left{
     56     50%;
     57     height:100%;
     58     float:left;
     59     display: table;
     60   }
     61   .top-left p{
     62     display: table-cell;
     63     vertical-align: middle;
     64   }
     65   .top-left img{
     66     auto;
     67     height:auto;
     68     max- 100%;
     69     max-height: 100%;
     70     margin-left: 2%;
     71   }
     72   .top-left span{
     73     display: inline-block;
     74     color:#fff;
     75     font-size: 1.3vw;
     76     font-weight: bold;
     77     font-family: "Microsoft YaHei UI";
     78   }
     79   .top-right{
     80     50%;
     81     height:100%;
     82     float:left;
     83   }
     84   .top-right div{
     85     100%;
     86     height:100%;
     87     position: relative;
     88     display: table;
     89   }
     90   .first-ul{
     91     list-style: none;
     92     position: absolute;
     93     right:2%;
     94     top:36%;
     95     27%;
     96   }
     97   .first-ul>li{
     98     display: inline;
     99   }
    100   .dropdown-menu li{
    101     text-align: center;
    102   }
    103   .nav-span{
    104     color:#fff;
    105     font-size: 0.8vw;
    106     font-family: "Microsoft YaHei UI";
    107     cursor: pointer;
    108   }
    109   .dropdown-menu{
    110     min- 98px;
    111   }
    112   .dropdown-menu li{
    113     margin-top:6%;
    114   }
    115   .dropdown-menu span{
    116     font-size: 0.6vw;
    117     font-family: "Microsoft YaHei UI";
    118     cursor: pointer;
    119     color:#121212;
    120   }
    121   .first-li{
    122     margin-right: 20%;
    123   }
    124   .base-img{
    125     vertical-align: text-top;
    126   }
    127 </style>
    128 <script>
    129   import * as types from '../../store/types'
    130   import {mapState} from 'vuex'
    131     export default{
    132         data(){
    133             return{
    134 
    135             }
    136         },
    137         methods:{
    138           logout(){
    139             var self = this;
    140             self.$store.commit(types.LOGOUT)
    141             self.$router.push({
    142               path: '/'
    143             })
    144 
    145           }
    146 
    147         },
    148         computed: mapState({
    149             userName: state => state.userName
    150         })
    151 
    152     }
    153 </script>
    View Code

    要说一句,就是vuex中的state里的值在页面刷新的时候会消失(即vuex中的状态管理是响应式的),因此我们使用localStorage来解决这个问题

    这就是为什么这么麻烦在state和localStorage中传来传去,是因为state的值刷新后会没了,而localStorage的值不能响应式地变化(Vue 仅可以对其管理的数据做响应式处理,可以理解为 data 中的数据,localStorage 并不在 Vue 的管理下,自然不会有响应特性);

    完整的项目地址为:

    https://github.com/yuwenjing0727/heating-power

  • 相关阅读:
    第三章 Selenide测试框架
    第二章 自动化测试的本质理解
    第一章 软件自动化测试的基础知识
    【算法学习】03---算法分析学习
    【算法学习】03---算法分析
    【算法学习】02---二分算法总结
    【算法学习】01---java基础以及算法基础常用类库
    前端自动化测试一些学习记录
    Ubuntu下安装Sublime3的Markdown插件
    octopress搭建记录
  • 原文地址:https://www.cnblogs.com/yuwenjing0727/p/7515034.html
Copyright © 2011-2022 走看看