jwt+vuex+localStorage+beforeEach实现登录验证

1 篇文章 0 订阅
1 篇文章 0 订阅

jwt+vuex+localStorage+beforeEach实现登录验证

  1. 涉及到的知识点
    ① 后台接口的搭建,以及解决跨域问题
    ② vuex的安装以及是使用
    ③ 路由以及路由守卫的应用
    ④ axios网络请求
    ⑤ jsonwebtoken登录权限验证
    ⑥ localStorage 本地存储
  • 一 1. 构建项目vuex-anli,npm 新增login登录路由
    router文件
  {
    path:'/login',
    component:()=>import('../views/login')
  }
  • 2 .构建login页面结构,安装引入 axios
    login文件
<template>
  <div>
     用户名:<input type="text" v-model="username"><br>
      密码:<input type="text" v-model="pwd">
      <button @click="login">登录</button>
  </div>
</template>
<script>
import axios from 'axios'
export default {
  data(){
      return{
          username:'',
          pwd:''
      }
  },
  methods:{
      login(){
          axios.post('http://localhost:5000/login','username='+this.usernamr
          +'&pwd='+this.pwd)
          .then(data=>{
              console.log(data);
          })
      }
  }
}
</script>
npm i -S axios 
  • 二 1. 创建server文件夹 构建后台
  • post请求 引入bodyParser,引入cors后台解决跨域,在后台给定一个user对象,用来验证登录是否正确,成功后返回一个token值
    token:jwt.sign({ })这里面写荷载数据,返回一个随机生成的id和username,在定义一个加密的字符串 let jiami

server文件

let express = require('express');
let bodyParser = require('body-parser')
let cors = require('cors');
let jwt = require('jsonwebtoken')

let user = {
    username:'kevin',
    pwd:123
}
let jiami ='idhsidhcsdjmsldmvpsdmdss'

let app =express();
app.use(cors())
app.use(bodyParser.urlencoded({extended:false}))

app.post('/login',(req,res)=>{
   if(req.body.username == user.username && req.body.pwd == user.pwd){
       res.send({
           msg:'success',
           token:jwt.sign({
               id:Math.floor(Math.random()*100000),
               username:user.username
           },jiami)

       })
   }else{
       res.send({
           msg:'登录失败'
       })
   }
})

app.listen(5000,function(){
    console.log(5000);
})
安装 express cors jsonwebtoken
npm i -S express cors jsonwebtoken
  • 三 1. 进行登录权限验证,在router页面,添加路由源信息(登录状态),使用路由前置守卫beforeEach,先看要跳转的路径,要不要有登录状态,if(to.meta.islogin),看登录状态islogin,如果有还为ture,那么就从vuex中获取数据去,否则跳转到登录页面
    router部分代码如下
//路由前置守卫
router.beforeEach((to,from,next)=>{
  if(to.meta.islogin){
    //从vuex中获取登录状态
     let vuex_islogin=store.state.islogin
     if(vuex_islogin){
       next()
     }else{
       next('/login')
     }
  }else{
     next()
  }
})
  • 2.在store中,定义登录状态islogin:false,以及改变登录状态的方法
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    islogin:false
  },
  mutations: {
    changeIsLogin(state){
      state.islogin=true
    }
  },
})
  • 注意:路由还没跳转哪,在beforeEach中访问不到this,这时需要把store用impo引进来
  • 3 点击登录后判断返回的msg状态,成功的话,调用store中的方法,改变state中定义的状态值
  • 4.把token存储到本地,并返回上一级
    login部分代码
  methods:{
      login(){
          axios.post('http://localhost:5000/login','username='+this.username
          +'&pwd='+this.pwd)
          .then(data=>{
              console.log(data);
              if(data.data.msg == 'success'){
                  alert(data.data.msg)
                  this.$store.commit('changeIsLogin')
                  //把token存储到本地
                  localStorage.setItem('vuex_login_token',data.data.token)
                  //返回上一层面
                  this.$router.back();
              }else{
                  alert(data.data.msg)
              }
          })
      }
  }


问题:清除缓存后就又回到login页面,从本地获取token,如果有说明登陆过,然后把vuex的state更改为ture
main.js 部分代码

//从本地获取token,如果有说明登陆过,然后把vuex的state更改为ture
let islogin = localStorage.getItem("vuex_login_token");
if(islogin){
  store.commit('changeIsLogin')
}

目录结构:

在这里插入图片描述
完整代码如下
server.js代码

let express = require('express');
let bodyParser = require('body-parser')
let cors = require('cors');
let jwt = require('jsonwebtoken')

let user = {
    username:'kevin',
    pwd:123
}
let jiami ='idhsidhcsdjmsldmvpsdmdss'

let app =express();
app.use(cors())
app.use(bodyParser.urlencoded({extended:false}))

app.post('/login',(req,res)=>{
   if(req.body.username == user.username && req.body.pwd == user.pwd){
       res.send({
           msg:'success',
           token:jwt.sign({
               id:Math.floor(Math.random()*100000),
               username:user.username
           },jiami)

       })
   }else{
       res.send({
           msg:'登录失败'
       })
   }
})

app.listen(5000,function(){
    console.log(5000);
})

router index.js代码

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

import store from '../store/index'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    meta:{
      islogin:true
    }
  },
  {
    path: '/about',
    name: 'About',
    meta:{
      islogin:true
    },
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path:'/login',
    component:()=>import('../views/login')
  }
]

const router = new VueRouter({
  routes
})

//路由前置守卫
router.beforeEach((to,from,next)=>{
  if(to.meta.islogin){
    //从vuex中获取登录状态
     let vuex_islogin=store.state.islogin
     if(vuex_islogin){
       next()
     }else{
       next('/login')
     }
  }else{
     next()
  }
})

export default router

store index.j’s代码

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    islogin:false
  },
  mutations: {
    changeIsLogin(state){
      state.islogin=true
    }
  },
})

login代码

<template>
  <div>
     用户名:<input type="text" v-model="username"><br>
      密码:<input type="text" v-model="pwd">
      <button @click="login">登录</button>
  </div>
</template>
<script>
import axios from 'axios'
export default {
  data(){
      return{
          username:'',
          pwd:''
      }
  },
  methods:{
      login(){
          axios.post('http://localhost:5000/login','username='+this.username
          +'&pwd='+this.pwd)
          .then(data=>{
              console.log(data);
              if(data.data.msg == 'success'){
                  alert(data.data.msg)
                  this.$store.commit('changeIsLogin')
                  //把token存储到本地
                  localStorage.setItem('vuex_login_token',data.data.token)
                  //返回上一层面
                  this.$router.back();
              }else{
                  alert(data.data.msg)
              }
          })
      }
  }
}
</script>

main.js代码

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false
//从本地获取token,如果有说明登陆过,然后把vuex的state更改为ture
let islogin = localStorage.getItem("vuex_login_token");
if(islogin){
  store.commit('changeIsLogin')
}

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值