vue项目中实现用户登录以及token验证


前言

用户登录这个功能在现在越来越普遍,我也就研究了一下,本文主要讲登录这个功能中token的验证功能,本例使用的是vue框架,如何实现用户登录功能的token验证,以及整个的逻辑关系,也会将涉及到的其他知识点都讲清楚,让大家更容易更透彻的了解这个功能。废话不多说,看正文!


一、总体逻辑图

总体就是这样,接下来细说每个部分涉及的知识点和代码。
在这里插入图片描述

二、各环节涉及知识点以及代码

1.jwt(这里只说用法,至于为什么用它,详细可查官网)

用于生成token和token的解析验证
1.JWT的组成:
          一个JWT实际上就是一个字符串,它由三部分组成:头部(Header)载荷(Payload)签名(signature).

  • JWT的组成:
    一个JWT实际上就是一个字符串,它由三部分组成:头部(Header)载荷(Payload)签名(signature).
  • token生成:
//content:需要传递的主题信息,如:用户id
//secretOrPrivateKey:加密的key
jwt.sign({
      var token = jwt.sign(content, secretOrPrivateKey, {
expiresIn: 10 // 多久过期,以s作为单位
});
  • token解析验证
jwt.verify(token, secretOrPrivateKey, function (err, decode) {
if (err) { // 当token过期,或这是一个伪造的token,或这是无效的token时会触发此逻辑
console.log(err)
} else {
console.log(decode.msg);//得到token中传递的token主题信息,如:用户id
}
})

实际项目后端接口项目代码如下:

//app.js  ,后端验证解析token接口,前端访问这个接口完整url为baseurl+'/validate'
const jwt = require('jsonwebtoken');
//创建服务器
let app=express();
//创建端口
app.listen(3000);
app.use(cors({

    origin:['http://127.0.0.1:8080','http://localhost:8080']
  
  }));
//挂载用户路由  前缀为/user
app.use('/user',userRouter);
//验证token的接口
let secret="mouchun.com";
app.get('/validate',(req,res)=>{
  let token = req.headers['user-token'];  //我们会把token放到我们自己设置的http的头authorization中,在这里可以直接拿到
  console.log(token);
  jwt.verify(token,secret,(err,decode)=>{     //验证token
      if(err){
          return res.json({
              code:1,
              data:'token失效了'
          })
      }else{
          // token合法  在这里,需要把token的时效延长,
          res.json({
              code:0,
              username:decode.username,
              token:jwt.sign({username:'Fan'},secret,{ //合法时,我们需要重新生成一个token,我们每次切换路由,都要重新生成一个token
                  expiresIn:20
              })
          })
      }
  })
})
//user.js,后端登录接口,前端访问这个接口完整url为baseurl+'/user/v1/login'
const jwt = require('jsonwebtoken');
const router=express.Router();
//添加用户登录路由
router.post('/v1/login',(req,res)=>{
    console.log(req.body);
    var $uname=req.body.uname;
    var $upwd=req.body.upwd;
    console.log($uname,$upwd);
    var sql='select*from lc_user where uname=? and upwd=?';
    pool.query(sql,[$uname,$upwd],(err,result)=>{
        if(err) throw err;
        if(result.length>0){
             // 把userId和其它相关信息加密成一个token,返回给前端
            let userInfo = {
                userId: result[0].uid,
            }
        // 生成token
        let token = jwt.sign(userInfo, "mouchun.com", {
            // expiresIn: "1000h"
            expiresIn: "10s"
        });
            res.send({
                code:200,
                msg:"登录成功",
                token:token
            });
        }else{
            res.send({
                code:0,
                msg:"登录失败",
            });
        }
    });
});

2.返回token并存入vuex做持久化

//store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import {validate} from '../service/getdata'
//引入常量函数
import mutations from './mutations'  
//vuex注册成为vue的插件
Vue.use(Vuex)
const state={
    login: false, //是否登录
    userInfo:null, //用户信息
    userToken:"",//用户登录token
}
//通过构造函数创建一个vuex的store
export default new Vuex.Store({
  //各个组件中共享的数据
  //定义了应用状态的数据结构,其类型可以为string,number,bool,object
  state,
  //定义方法改变状态
  mutations,
  //发送异步请求
  actions: {
    //验证token方法
    async validate({commit}){
      let r = await validate(); //调用user.js中的validate方法,也就是调用验证接口
      if(r.code === 0){
        // commit('setUser',r.username)
        this.userToken=r.token //我们说了,验证通过,或者每次切换路由时,都要重新生成token
      }
      return r.code === 0;  //返回token是否失效,true或者false
    }

  },
  //store的计算属性 第一次计算的结果会缓存
  getters(){

  },
  modules: {
  }
})

3.路由守卫

//router/index.js
export default new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      component: login
    },
    {
      path: '/',
      name: 'Index',
      component: Index,
      //通过添加meta属性,来决定这个页面是否需要登录才能够查看,需要则加这个属性,否则不加
      // meta:{
      //   needLogin:true
      // }    
    }
  ]
})
//main.js
import router from './router'
import store from './store'
import axios from 'axios'
//添加到原型对象
Vue.prototype.axios=axios;
//每一次切换路由时,都执行这个导航守卫
router.beforeEach(async (to,from,next)=>{
  //store.dispatch含有异步操作,数据提交至 actions ,可用于向后台提交数据
  let isLogin = await store.dispatch('validate')  //判断是否登录了
  // needLogin  表示哪些路由需要在登录条件下才能访问
  // console.log(to);
  let needLogin = to.matched.some(match=>match.meta.needLogin)
  if(needLogin){
    //需要登录
    if(isLogin){
      //登录过了
      next()
    }else{
      //没有登录
      next('/login')
    }
  }else{
    //不需要登录
    if(isLogin && to.path === '/login'){  //如果你访问login页面,则给你跳到首页面,因为不需要登录
      // next('/')
    }else{
      next()
    }
  }
})
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

4.axios请求拦截

//axios.js,axios的封装,具体可以查其他资料,这里主要展示请求拦截
import axios from "axios";

//请求拦截
   axios.interceptors.request.use(
        config => {
          console.log('config',config);
          // 从vuex读取token的值,给请求头添加laohu-token
          if (store.state.userToken) {
              config.headers['user-token'] = store.state.userToken;//如果存在token,将token放入请求头
          }
          return config
      },
        err => {
        return Promise.reject(err)
        })

总结

举个栗子:

  1. 发起任意请求axios.get/post(url)
  2. 跳至路由守卫,判断即将跳转的页面是否需要登录,并且现在是否已经登录,请求后端验证端口,返回响应
  3. 假如即将跳转页面需要登录,现在未登录跳转登录页
  4. 用户进行登录,请求后端登录接口,生成token,响应回前端
  5. 前端接收并保存
  6. 再次发起请求,路由守卫判断
  7. 假如即将跳转页面需要登录,现在已经登录,跳至axios请求拦截
  8. 携带token发起请求
  9. 后端接受,返回相应数据

综上所述:以上就是今天要讲的内容,本文仅仅简单介绍了token的使用,而还没有考虑token失效的情况,下一次再说!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值