mock+vuex+axios利用token实现用户登录验证

思路:

  1. mock模拟用户数据
  2. axios请求接口,
  3. router中进行needLogin的判断,true为需要登录才能进入此页面
  4. vuex中,将在login.vue中获取的用户名和密码进行验证
  5. 验证后,拿到token和usertitle,将token存储到sessionStorage中,usertitle存储至vuex的title,在home.vue中显示
  6. 前端每次跳转时,就在main.js使用导航守卫(vue-router.beforeEach)判断 sessionStorage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面。
  7. home.vue的退出可注销登录,注销后,就清除sessionStorage里的token信息并跳转到登录页面
    mock+vuex+axios利用token实现用户登录验证_第1张图片
    mock—mock.js
import Mock from 'mockjs'
const Random = Mock.Random
//home页面的表格数据
Mock.mock('/getUser',{
     
    'data|3': [{
     
        'name': Random.cname(),
        'age': Random.natural(22, 40),
        'date': Random.date('yyyy-MM-dd'),
        'address': Random.county(true)
      }]
})
//登录数据
Mock.mock('/getLogin',
  {
     
    "error_code": 0,
    "data": [{
     
      "id": '1',
      "usertitle": "管理员",
      "username": "admin",
      "password": "123456",
      "token": "123133123",
     },
     {
     
      "id": '2',
      "usertitle": "用户",
      "username": "root",
      "password": "root",
      "token": "65454634",
     }
    ]
  }
)

request----http.js

import axios from 'axios';
axios.defaults.timeout = 5000;
axios.defaults.baseURL ='';
//http request 拦截器
axios.interceptors.request.use(
  config => {
     
    // const token = getCookie('名称');注意使用的时候需要引入cookie方法,推荐js-cookie
    config.data = JSON.stringify(config.data);
    config.headers = {
     
      'Content-Type':'application/x-www-form-urlencoded'
    }
    // if(token){
     
    //   config.params = {'token':token}
    // }
    return config;
  },
  error => {
     
    return Promise.reject(err);
  }
);

//http response 拦截器
axios.interceptors.response.use(
  response => {
     
    if(response.data.errCode ==2){
     
      router.push({
     
        path:"/login",
        querry:{
     redirect:router.currentRoute.fullPath}//从哪个页面跳转
      })
    }
    return response;
  },
  error => {
     
    return Promise.reject(error)
  }
)

//  封装get方法,返回promise对象
export function get(url,params={
     }){
     
  return new Promise((resolve,reject) => {
     
    axios.get(url,{
     
      params:params
    })
    .then(response => {
     
      resolve(response.data);
    })
    .catch(err => {
     
      reject(err)
    })
  })
}
// 封装post请求
export function post(url,data = {
     }){
     
  return new Promise((resolve,reject) => {
     
    axios.post(url,data)
         .then(response => {
     
           resolve(response.data);
         },err => {
     
           reject(err)
         })
  })
}
// 封装getAwait方法,返回async方法
export async function getAwait(url,params={
     }){
     
  let res=await axios.get(url,{
     params:params})
  res=res.data
  return res
}
// 封装getAwait方法,返回async方法
export async function postAwait(url,data={
     }){
     
  let res=await axios.post(url,data)
  res=res.data
  return res
}

request—api.js

import {
      get,getAwait} from './http'

//登录
export function getLogin(username,password){
     
	return get('/getLogin',username,password)
}
//home页面表格信息
export  function getUserInfo(param){
     
	return getAwait('/getUser',param)
}

router—index.js。设置needLogin后可自行进行验证,会发现,即使将浏览器URL地址改为/或者/home,页面不会跳到/或/home页面,只有/login能进入

import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/pages/login'
import Home from '@/pages/home'

Vue.use(Router)

export default new Router({
     
  routes: [
    {
      path: '/', component: Home ,meta:{
     needLogin:true}},//needLogin判断是否需要登录才可以进入
    {
      path: '/home', component: Home ,meta:{
     needLogin:true}},
    {
      path: '/login', component: Login },
  ]
})

store—store.js。讲login.vue页面获取来的user和pwd跟mock中的username和password进行匹配,匹配成功则将相应token存储至session,usertitle存储至vuex的title,供home.vue显示使用

import Vue from 'vue';
import Vuex from 'vuex';
import {
      getLogin } from "../request/api.js";
import router from '../router/index'
Vue.use(Vuex);

const state = {
     
    ruleForm: {
     
        user:'',
        pwd:''
    },
   result:null,
   title:''
}
const mutations={
     
    setLogin(state,param){
     
        state.result=param.result
    },
    setUser(state,n){
     
        state.ruleForm.user=n
    },
    setPwd(state,n){
     
        state.ruleForm.pwd=n
    },
}
const actions={
     
    getLogin(context){
     
        getLogin().then(res => {
     
            console.log(res.data);
            context.commit('setLogin',{
     result:res.data})
            let len = res.data.length;
            let userNameArr = [];
            let passWordArr = [];
            let ses = window.sessionStorage;
            for (var i = 0; i < len; i++) {
     
              userNameArr.push(res.data[i].username);
              passWordArr.push(res.data[i].password);
            }
            if (userNameArr.indexOf(state.ruleForm.user) === -1) {
     
              alert("账号不存在!");
            } else {
     
              var index = userNameArr.indexOf(state.ruleForm.user);
              if (passWordArr[index] === state.ruleForm.pwd) {
     
                // 把token放在sessionStorage中
                ses.setItem("data", res.data[index].token);
                console.log(ses,'ses')
                state.title=res.data[index].usertitle
                //跳转到首页
                router.push("/");
              } else {
     
                alert("密码错误!");
              }
            }
          });
    },
    loginOut(){
     
        // 注销后 清除session信息 ,并返回登录页
        window.sessionStorage.removeItem('data');
        router.push('/login'); 
    }
}
export default new Vuex.Store({
     
    state,
    mutations,
    actions
})

pages----login.vue


<template>
  <div id="login">
    <el-form
      :model="ruleForm"
      status-icon
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="账号" prop="user">
        <el-input type="text" v-model="ruleForm.user" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="pwd">
        <el-input type="password" v-model="ruleForm.pwd" autocomplete="off" @keyup.enter.native="submitForm"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import {
      getLogin } from "../request/api.js";
import axios from "axios";
export default {
     
  name: "Login",
  data() {
     
    return {
     
      ruleForm: {
     
        user:'',
        pwd:''
      },
      rules: {
     
        user: [{
      required: true, trigger: "blur" }],
        pwd: [{
      required: true, trigger: "blur" }]
      },
    };
  },
  computed: {
     
    user: {
     
      get() {
     
        return this.$store.state.ruleForm.user;
      },
      set(newVal) {
     
        this.$store.commit("setUser", newVal);
      }
    },
     pwd: {
     
      get() {
     
        return this.$store.state.ruleForm.pwd;
      },
      set(newVal) {
     
        this.$store.commit("setPwd", newVal);
      }
    },
  },
  created() {
     

  },
  methods: {
     
    submitForm(formName) {
     
      this.user=this.ruleForm.user
      this.pwd=this.ruleForm.pwd
      this.$refs.ruleForm.validate(valid => {
     
        if (valid) {
     
          this.$store.dispatch('getLogin')
        } else {
     
          console.log("用户名或密码错误");
        }
      });
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

登录页面
mock+vuex+axios利用token实现用户登录验证_第2张图片
pages—home.vue

<template>
  <div id="login">
    <h1>{
     {
     this.$store.state.title}}</h1>
    <el-button @click="loginOut">退出</el-button>
     <el-table
      :data="tableData"
      style="width: 100%">
       <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
       <el-table-column
        prop="age"
        label="年龄"
        width="180">
      </el-table-column>
      <el-table-column
        prop="date"
        label="日期"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址">
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import {
     getUserInfo} from '../request/api.js'
export default {
     
  name: 'Home',
  data () {
     
    return {
     
      tableData:[]
    }
  },
  created(){
     
    getUserInfo().then(res => {
     
    console.log(res)
    this.tableData = res.data
  })

  },
  methods:{
     
    loginOut(){
     
      this.$store.dispatch('loginOut')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

home.vue登录后页面,按退出则清除session信息,并返回登录页
mock+vuex+axios利用token实现用户登录验证_第3张图片
main.js
mock+vuex+axios利用token实现用户登录验证_第4张图片

你可能感兴趣的:(vue)