Vue实现用户登录及token验证

 写博客不是为了博眼球 而是为了记笔记 

请勿复制全部代码防止错乱,这里放源码是为了个人做笔记 

    //登录
    login: params => {
        return API.POST('/accounts/login', qs.stringify(params))
    } 

     login.vue里          

<template>
    <div class="loginpage">
        <div class="login-bg">
           <div class="title">
                <img src="../assets/loginlogo.png">
                <div>
                     <p>网络安全某某某某系统</p>
                     <p class="english">NETWORK SECURITY XXXX SYSYTEM</p>   
                </div>
            </div> 
        <div class="logincenterimg">  
                <div class="login-form">  
                    <el-form :model="ruleForm2" :rules="rules2" ref="ruleForm2" label-position="left" label-width="0" class="demo-ruleForm login-container">
                        <strong class="logintitle" ref="title">用户登录</strong>
                        <el-form-item prop="username">
                            <el-input type="text" v-model="ruleForm2.username" auto-complete="off" placeholder="请输入账号">
                            </el-input>
                        </el-form-item>
                        <el-form-item prop="password"  style="margin-top:58px;">
                            <el-input type="password" v-model="ruleForm2.password" auto-complete="off" placeholder="请输入密码" @keyup.enter.native="loginSys">
                            </el-input>
                        </el-form-item>
                        <el-form-item prop="imageCode"  class="ipt-vcode">
                        <el-input type="text" v-model="ruleForm2.vcode" auto-complete="off" placeholder="请输入验证码">
                            <i slot="prefix" class="el-input__icon prefix-vcode-icon"></i>
                        </el-input>
                        </el-form-item> 
                        <img :src="ruleForm2.vcodeImg" id="code" class="logincode" @click="changevCode"/> 
                        <!-- <el-form-item style="width:100%;"> -->
                            <el-button class="loginbtn" @click.prevent="loginSys" >登录</el-button> 
                    </el-form>
                </div> 
            </div> 
        </div> 
    </div>
</template>

<script>
import API from '../axios/api_data.js'
export default {
    data () { 
        return { 
            ruleForm2: {
                username: '',
                password: ''
            },
            rules2: {
                username: [
                    { required: true, message: '请输入用户名', trigger: 'blur' }, 
                ],
                password: [
                    { required: true, message: '请输入密码', trigger: 'blur' }, 
                ]
                // ,
                // vcode:[
                //     {required: true, message: '请输入验证码', trigger: 'blur'}
                // ]
            },
            // checked: true,
            errorbox:{
                errshow:false,
                errmsg:'',
            } 
        };
     
    },
    mounted:function(){
        // this.verificationCode();
    },
    created:function(){}, 
    methods: {
        loginSys: function (ev) {
          // 调用接口之前做表单验证操作
          this.$refs['ruleForm2'].validate(valid => {
            if (valid) {
              // 表单验证通过
              // 调用登录接口
              let params = {
                username: this.ruleForm2.username,
                password: this.ruleForm2.password
                // ,imageCode:this.ruleForm2.imageCode
              }
              // 调用接口,提交用户登录信息
              API.login(params).then(res => {
                if (res.code === 0) {
                    alert(res.data.token)
                  // 存储token
                  localStorage.setItem('mytoken', res.data.token)
                  // 登录成功,跳转到主页
                  this.$router.push({ path: '/' })
                } else {
                  // 登录失败,提示一下用户
                  this.$message({
                    message: res.message,
                    type: 'error'
                  })
                }
              })
            }
          })
        }
      }
}
</script>
 
<style lang="less">
*{
  padding: 0;margin: 0;
}
.loginpage{
    padding-top: 165px;
    width: 100%;
    height: 100%;
    min-height: 915px; 
    background: url(../assets/loginbg.png);
    .title{
        display:flex;
        justify-content: center;
        text-align:center; 
       font-size:34px;
       color:#00ffff;
       margin-bottom:65px;
       img{
          width:72px;
          height:72px;
          margin-right:30px;
       }
       .english{
          font-size:18px;
          color:#fff;
       }
    }
}
.logincenterimg{
    width: 750px;
    height: 600px;
    background: url(../assets/loginbg2.png) no-repeat center center;   
    margin:0px auto;
    position:relative;
    .login-form{
        position: absolute;
        top: 100px;
        left: 142px;
        text-align:center;
        .el-form-item{
            margin-left:100px;
        }
        .logintitle{
            display: inline-block;
            margin-bottom: 80px;
            font-size:24px;
            color:#5ea5d7;
        }
        input{
            border:none;
            background:#041c3b;
            margin-bottom: 15px;
            height: 46px;
            font-size:20px;
            color:#155a8c;
        }
        input::-webkit-input-placeholder {
            color: #2170a4;
        } 
    }
}
.loginbtn{
    width: 484px;
    height: 62px;
    background:#2c94ff;
    font-size:20px;
    color:#fff;
    border:none;
    border-radius:15px 0px 15px 0px;
}
.loginpage{
    width: 100%;
    height: 100%; 
}
.el-form-item{
    width:300px;
}
</style>

index.js里 


import axios from 'axios';
import router from '../router' ;
import { Message } from 'element-ui';

let URL_PREFIX;

if (process.env.NODE_ENV === 'development') {
    //开发环境下的代理地址,解决本地跨域跨域,配置在config目录下的index.js dev.proxyTable中
    URL_PREFIX = "/api"
} else {
    //生产环境下的地址
    URL_PREFIX = '/';
}
// 拦截器处理token
axios.interceptors.request.use(function (config) {
  let token = localStorage.getItem('mytoken')
  if (token) {
    config.headers['Authorization'] = token
  }
  return config
}, function (error) {
  return Promise.reject(error)
})

export const uploadInfo = () => {
  return {
    url: baseURL,
    token: localStorage.getItem('mytoken')
  }
}

// 登录验证
export const checkUser = params => {
  return axios.post('login', params).then(res => res.data)
}

// 退出登录
export const logout = params => {
  return axios.get('logout', params).then(res => res.data)
}


const $ajax = axios.create({
    baseURL: URL_PREFIX, 
});

$ajax.interceptors.response.use(function (response) {
	// 对响应数据做点什么   
    localStorage.setItem('is_expired',response.data.is_expired );  
	if(response.data.is_expired && !response.data.success){ //是否过期,如果过期,跳转到/login 登录页面 
        router.push('/login');
        localStorage.removeItem('user');
        localStorage.removeItem('permidlist');  
	} 
    if(!response.data.success && response.data.msg){ //失败并且有失败信息
        Message.error(response.data.msg);
    }
    return response;
}, function (error) {
    if(error && error.response){
        switch(error.response.status){
            case 400: 
                Message.error('错误请求');
                break;
            case 401: 
                Message.error('访问被拒绝');
                break;
            case 403: 
                Message.error('禁止访问');
                break;
            case 404: 
                //Message.error('请求错误,未找到资源');
                router.push('/404');
                break;
            case 408: 
                Message.error('请求超时');
                break;
            case 500: 
                //Message.error('服务器端出错');
                router.push('/500');
                break;
            case 502: 
                Message.error('网络错误');
                break;
            case 503: 
                Message.error('服务不可用');
                break;
            case 504: 
                Message.error('网关超时');
                break;
            default:
                Message.error('连接错误'+error.response.status);

        } 
    }else{
        Message.error('网络出现问题,请稍后再试');
    }
    

	return Promise.reject(error);
});
// 通用方法
export const POST = (url, params) => {
  return $ajax.post(`${url}/`, params).then(res => res.data)
}
export const GET = (url, params) => {
  return $ajax.get(`${url}/`, {params: params}).then(res => res.data)
}
export default $ajax

main.js里 

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App'
import router from './router' 
import store from './store/store'
import $ajax from './axios/index'
import qs from 'qs'
import './assets/theme/index.css'
import './assets/theme/common.css'
import ElementUI from 'element-ui'

import Global from './global/global'


import './assets/icon/iconfont.css'

Vue.use(Vuex)

Vue.use(ElementUI)

// 全局导航过滤(其实就是拦截路由请求)
router.beforeEach((to, from, next) => {
  let user = localStorage.getItem('mytoken')
  if (user) {
    // 允许通过,按照正常的逻辑向下跳转
    next()
  } else {
    // 登陆的路由是不需要验证权限的
    if (to.path !== '/login') {
      // 如果没有权限,从新跳转到登录页面
      next({path: '/login'})
    } else {
      // 是登录页,直接跳转到登录页面
      next()
    }
  }
})
Vue.prototype.qs = qs

Vue.prototype.$ajax = $ajax

Vue.prototype.store = store

Vue.prototype.global = Global

Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
 
});
 

猜你喜欢

转载自blog.csdn.net/qq_42177730/article/details/102461197