0


token + localstorage 验证登录(vue)详细教程

🚩概要

  • token : 本质是验证身份的令牌,一般由用户通过账户密码登录后,服务端把这些凭证通过加密等一些列操作后得到的字符串。
  • token 登录流程: - 客户端用账户密码请求登录;- 服务端接收请求,验证账户密码;- 验证成功后,服务端发送token给客户端;- 客户端接收到token后保存,可以存储于sessionstorage或localstorage;- 客户端每次请求,需要将携带token发送给服务端;- 服务端接收请求,验证token,验证成功则响应请求返回请求数据;
  • token 验证优点: - token 存储于客户端,不会对服务端造成压力,即便是服务端集群,也不会增加维护成本;- token 在前端可以不保存于 Cookie 中,避免CSRF攻击,提升数据的安全性;- token 下发后,在有效期内长久生效,服务端想回收 token 权限非常困难;

✌️步骤:

1.demo构建

  • 前端:采用 token + localStorage + vuex 做令牌存储验证,包含 axios 二次封装、路由守卫、api 模块化等操作;
  • 后端:采用👉 mock.js 请求模拟,模拟登录接口测试数据获取等 ; 通过vueCLI脚手架搭建,包含以下基本结构:

项目结构

2.后端Mock

mock 文件夹下新建 index.js,编写登录与数据获取测试接口以便后面模拟请求调取,注意需要在 main.js 引入

const Mock =require('mockjs');// 登录接口
Mock.mock('/login','post',(option)=>{// 解析请求体 body 中数据let response =JSON.parse(option.body);return{status:200,message:'请求成功',data: response,token:'authorization-xxxxxx'// 模拟后端返回 token}})// 数据请求模拟
Mock.mock('/data','get',(option)=>{return{status:200,message:"请求成功",data:[1,2,3,4,5]}})

main.js
在这里插入图片描述

3、login.vue

<template><div><inputtype="text"v-model="form.username"placeholder="用户名"><inputtype="password"v-model="form.password"placeholder="密码"><button@click="login">登录</button></div></template><script>import{ mapMutations }from'vuex'import{ Login }from'../api/api.js'exportdefault{name:'Login',data(){return{form:{username:'',password:''},token:''}},methods:{...mapMutations(['setToken']),login(){if(this.form.username ===''||this.form.password ===''){alert('账号密码不能为空');}else{let form =newFormData();
        form.append('username',this.form.username);// 密码一般要加密处理,根据项目需求而定
        form.append('password',this.form.password);Login(form).then(res=>{
          console.log(res);this.token ='Bearer'+ res.data.token;this.setToken({token:this.token});this.$router.push('/home');alert('登录成功');}).catch(err=>{alert('账号密码错误');
          console.log(err)})}}}}</script></script>

4、home.vue

<template><divclass="hello"><h1>{{ msg }}</h1><button@click="getData">获取数据</button><button@click="clearToken">清除token</button></div></template><script>import{ getData }from'@/api/api';exportdefault{name:"Home",data(){return{msg:'数据等待获取'}},methods:{getData(){getData().then(res=>{
        console.log(res)this.msg = res.data.data
      })},clearToken(){
      localStorage.removeItem('token')}}};</script>

5、路由router

添加前置路由守卫,访问其他页面需携带 token 并进行验证

import Vue from"vue";import VueRouter from"vue-router";consthome=()=>import("@/components/Home.vue");constlogin=()=>import("@/components/Login.vue");

Vue.use(VueRouter);const routes =[{path:"/",redirect:"/login"},{path:"/login",name:"login",component: login
  },{path:"/home",name:"home",component: home
  }];const router =newVueRouter({mode:"history",base: process.env.BASE_URL,
  routes,});/**
*    重写 router.prototype.push 避免同时跳转相同路径报错
*/const originalPush =VueRouter.prototype.push;VueRouter.prototype.push=functionpush(location, onResolve, onReject){if(onResolve || onReject)returnoriginalPush.call(this, location, onResolve, onReject)returnoriginalPush.call(this, location).catch(err=> err)}// 前置路由守卫
router.beforeEach((to, from, next)=>{if(to.path ==='/login'){next();}else{let token = localStorage.getItem('token');if(token ===null|| token ===''){next('/login')}else{next()}}})exportdefault router;

6、vuex存储

token 登录获取到后,一般要本地 localStorage 和 vuex 中存一份, 存 vuex 目的是用于需要授权接口调用,存入 vuex 便于统一管理;localStorage 数据是存放在硬盘中, vuex 数据是存储内存中读取速度更快。

import Vue from"vue";import Vuex from"vuex";

Vue.use(Vuex);exportdefaultnewVuex.Store({state:{// 存储tokentoken: localStorage.getItem("token")? localStorage.getItem("token"):""},mutations:{// 修改token ,并将token 存入localStoragesetToken(state, user){
      state.token = user.token;
      localStorage.setItem("token",user.token);}},});

7、axios 二次封装

一般大型项目都需要对 axios 二次封装,以便请求统一处理与接口模块化管理

import router from"@/router";import axios from"axios"import qs from"qs"// 配置开发&生产环境接口,根据 node 环境变量来进行判断const devBaseURL ='/';const proBaseURL ='http://prod.xxxx';const baseURL = process.env.NODE_ENV==="development"? devBaseURL : proBaseURL;const instance = axios.create({baseURL: baseURL,timeout:5000,// 设置超时时间withCredentials:true// 设置是否允许跨域传递的 cookie 携带凭证})// 配置请求参数传递格式,默认是JSON格式,根据服务器决定
instance.defaults.headers['Content-Type']='application/x-www-form-urlencoded';
instance.defaults.transformRequest=data=> qs.stringify(data)// 配置 axios 请求拦截器, 配置 token 登录认证
instance.interceptors.request.use(config=>{// 配置每次发送请求之前判断是否存在 token,存在则在请求头 header 上添加 token,let token = localStorage.getItem('token');
    token &&(config.headers.Authorization = token);return config;},error=>{return Promise.reject(error)})// 配置 axios 响应拦截器
instance.interceptors.response.use(// 判断返回状态码,进行对应的数据返回与异常抛出操作response=>{if(response.status ===200){return Promise.resolve(response)}else{return Promise.reject(response)}},// 配置服务器状态码不是200的情况error=>{if(error.response){switch(error.response.status){// 401: 未登录case401: 
          localStorage.removeItem('token');alert('连接超时,请重新登录');
          router.push({path:'/'});break// 403: 登录过期case403:alert('登录过期,请重新登录');
          localStorage.removeItem('token');
          router.push({path:'/'});break// 404: 请求不存在case404:alert('网络请求不存在');break// 500: 服务错误case500:alert('网络请求有误');default:alert('服务错误');}//return Promise.reject('服务错误')}else{// 配置服务器没有返回结果情况if(!window.navigator.onLine){// 断网情况,进行断网处理return}return Promise.reject(error)}})exportdefault instance

8、api.js

对接口模块化处理,方便管理调用

import request from'../utlls/request'exportfunctionLogin(params){returnrequest({method:'post',url:'/login',data: params
  })}exportfunctiongetData(params){returnrequest({method:'get',url:'/data',
    params
  })}

✔️测试

  • 第一登录后,打印请求结果,可看到模拟请求返回数据中 token 字段token获取
  • 登录后,点击‘获取数据’按钮,打印请求结果,可看到请求头 Authorization 已包含 token在这里插入图片描述
  • 点击‘清除token’按钮,刷新页面则会自动退回登录界面

至此登录 demo 完成,若有问题欢迎指正,编写不易还望三连!😘😘😘

标签: 前端 vue.js web安全

本文转载自: https://blog.csdn.net/Centenario_0/article/details/128287551
版权归原作者 詹姆斯bind 所有, 如有侵权,请联系我们删除。

“token + localstorage 验证登录(vue)详细教程”的评论:

还没有评论