JWT登录验证前后端设计与实现笔记

设计内容

前端

  1. 配置全局前置路由守卫
  2. axios拦截器
  3. 登录页面和主页

后端

  1. JWT的封装
  2. 登录接口
  3. 中间件放行
  4. mysql数据库的连接
    在这里插入图片描述

详细设计

路由设计

配置全局前置守卫,如果访问的是登录页面则放行,不是则进入判断是否有token,没有则拦截回到登录页面,有则放行访问。

router.beforeEach((to, from, next) => {
   
  //如果是访问Login,则直接通过
  if(to.name==='Login'){
   
    next();
  }else{
   
    //如果没有token则进入登录页面
    if(!localStorage.getItem("token")){
   
      next({
   
        path:'/login'
      });
    }else{
   
        next();
    }
  }
});

axios拦截器

配置响应拦截器,拿到后端传来的token并保存到localStorage中,如果后端传回来了401错误(token失效),就会删除localStorage中的token并回到登录页面。

// 响应拦截
axios.interceptors.response.use(function (response) {
   
   //拿到响应里的token
   console.log(response);
   const authorization  = response.data.token;
   console.log(authorization);
   authorization && localStorage.setItem("token",authorization);
   return response;
 }, function (error) {
   
   const {
    status } = error.response;
   if(status===401){
   
      localStorage.removeItem("token");
      router.push("/login");
   }
   return Promise.reject(error);
 });

配置请求拦截器,把localStorage中的token加到请求头中的Authorization中。

//请求拦截
axios.interceptors.request.use(function (config) {
   
   const token = localStorage.getItem("token");
   //请求时带上token,给后端认证
   config.headers.Authorization = `${
     token}`;
   return config;
 }, function (error) {
   
   return Promise.reject(error);
 });

登录页面和主页

在这里插入图片描述
登录方法写得比较简单,请求登录接口,判断后端返回的结果。

LoginHandle(){
   
   if(this.loginForm.password || this.loginForm.username){
   
      axios.post("http://localhost:3000/login",this.loginForm).then(res=>{
   
         if(res.data.status == "success"){
   
            this.$router.push("/mainbox");
         }else{
   
            ElMessage.error('用户名或密码错误!');
         }
      })
   }else{
   
      ElMessage.error('请填写账号和密码!');
   }
}

访问主页时会请求后端的接口,主页请求时所携带的token给后端处理,后端会判断 token是否过期,如果过期后端就回应401错误码,401错误码被axios的响应拦截器处理,跳回登录页面。

mounted(){
   
   this.getIndex();
},
methods:{
   
   getIndex(){
   
      axios.get('http://localhost:3000/bill').then(res=>{
   
         console.log(res.data);
      })
   }
}

JWT封装

JWT是JSON Web Token的缩写,jsonwebtoken这个模块有两个常用的方法,sign()和verify()作用分别是生成token和验证token,sign()方法需要3个基本的参数,1.加密内容,2.密钥,3.过期时间。verify()方法有2个基本参数,1.加密内容,2.密钥。

const jwt = require("jsonwebtoken");
const secret = "samrol";
const JWT = {
   
   generate(value,expires){
   
      return jwt.sign(value,secret,{
   expiresIn:expires});
   },
   verify(token){
   
      try{
   
         return jwt.verify(token,secret);
      }catch(error){
   
         return false;
      }
   }
}
module.exports = JWT;

登录接口

访问/login时后端会做:拿到前端请求带过来的账户和密码,连接数据库,查询登录信息是否正确,不正确则回应登录错误给前端,信息正确:生成token,把token添加到header的Authorization里,返回成功信息。

const express = require("express");
const router = express.Router();
const mysql2 = require("mysql2");
const JWT = require("../util/JWT");
const getDBConfig = require("../util/mysql");

router.post("/",async (req,res)=>{
   
   const {
   username,password} = req.body;
   const config = getDBConfig();
   const promisePool = mysql2.createPool(config).promise();
   var user = await promisePool.query(`select * from user where name=? and password=?`,[username,password]);
   //登陆成功
   if(user[0].length>0){
   
      //生成token
      const token = JWT.generate({
   username,password},"10s");
      //设置头部
      res.header("Authorization",token);
      res.send({
   status:"success",message:"登录成功",token});
   }else{
   
      res.send({
   status:"error",message:"用户名或密码错误"});
   }
})

module.exports = router;

补充一个数据库连接配置

function getDBConfig(){
   
   return{
   
      host:'127.0.0.1',
      port:3306,
      user:'root',	
      password:'',
      database:'vue_test',
   }
}

module.exports = getDBConfig;

接口拦截中间键

接收到的每次请求都需要通过这个中间件,如果是login接口则直接放行,其他的则需要通过验证前端携带的token是否过期来判断能否放行,如果过期则返回401错误码来提醒用户token过期需要重新登录。

app.use((req,res,next)=>{
   
   if(req.url==="/login"){
   
      next();
      return;
   }
   const token = req.headers['authorization']//.split(" ")[1];
   if(token){
   
      var payload = JWT.verify(token);
      if(JWT.verify(token)){
   
         const newToken = JWT.generate({
   
            username:payload.username,
            password:payload.password,
         },"10s");
         res.header("Authorization",newToken);
         next();
      }else{
   
         res.status(401).send({
   errCode:"-1",errorInfo:"token过期!"});
      }
   }
})

相关推荐

  1. gin使用jwt登录验证

    2024-02-18 07:10:01       63 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-18 07:10:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-18 07:10:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-18 07:10:01       82 阅读
  4. Python语言-面向对象

    2024-02-18 07:10:01       91 阅读

热门阅读

  1. Docker 第十五章 : Docker 三剑客之 Compose(一)

    2024-02-18 07:10:01       42 阅读
  2. RabbitMQ

    RabbitMQ

    2024-02-18 07:10:01      52 阅读
  3. rtt设备io框架面向对象学习-硬件rtc设备

    2024-02-18 07:10:01       58 阅读
  4. Vue3.0(八):网络请求库axios

    2024-02-18 07:10:01       57 阅读