1. 后端代码概览

server/router/index.js

请求

router.get('/getUserInfo', function (req, res, next) { // 登录请求
res.send('success')
}) router.get('/authorization', (req, res, next) => { // 获取验证请求
const userName = req.userName // 从app.js中拿到userName
res.send({
code: 200,
mes: 'success',
data: {
token: jwt.sign({
name: userName
}, 'abcd', { // 重新生成一个新的Token, 返回给前端
expiresIn: '1d'
}),
rules: {
page: {
home: true,
home_index: true,
about: true,
argu: true,
count_to: true,
menu_page: true,
upload: true,
form: true,
folder_tree: true,
table_page: true,
render_page: true,
split_pane: true,
parent: true,
child: true,
named_view: true,
store: true,
main: true
},
component: {
edit_button: true,
publish_button: false
}
}
}
})
})

server/router/index.js

登录接口

const getPasswordByName = (name) => {
return { password: '123' }
} router.post('/login', function (req, res, next) {
const { userName, password } = req.body
if (userName) {
const userInfo = password ? getPasswordByName(userName) : ''
if (!userInfo || !password || userInfo.password !== password) {
res.status(401).send({
code: 401,
mes: 'user name or password is wrong',
data: {}
})
} else {
res.send({
code: 200,
mes: 'success',
data: {
token: jwt.sign({ name: userName }, 'abcd', { // jwt--jsonwebtoken第三方库生成Token
expiresIn: '1d' // 过期时间 1day/H 60 ; 一天/小时 60秒
})
}
})
}
} else {
res.status(401).send({
code: 401,
mes: 'user name is empty',
data: {}
})
}
})

server/views/app.js

Token校验

const whiteListUrl = { // 白名单 不需要做校验的接口
get: [],
post: [
'/index/login'
]
} const hasOneOf = (str, arr) => {
return arr.some(item => item.includes(str))
} app.all('*', (req, res, next) => {
let method = req.method.toLowerCase() // 获取当前请求方式
let path = req.path // 获取当前请求路径
if (whiteListUrl[method] && hasOneOf(path, whiteListUrl[method])) next() // 过滤 有些接口不需要做Token校验
else { // 需要校验的接口
const token = req.headers.authorization // 取到请求头中Token
if (!token) res.status(401).send('there is no token, please login')
else {
jwt.verify(token, 'abcd', (error, decode) => { // jsonwebtoken第三方库校验Token
if (error) {
res.send({
code: 401,
mes: 'token error',
data: {}
})
} else {
req.userName = decode.name
next()
}
})
}
}
})

2. 登录以及Token处理

  • npm i js-cookie md5 -S
  • src/views/login.vue

<template>
<div>
<Input v-model="userName" placeholder="账号"></Input>
<Input v-model="password" type="password" placeholder="密码"></Input>
<Button type="primary" @click="handleSubmit">登录</Button>
</div>
</template> <script>
import { mapActions } from 'vuex'
export default {
name: 'login_page',
data () {
return {
userName: '',
password: ''
}
},
methods: {
...mapActions(['login']),
handleSubmit () {
this.login({
userName: this.userName,
password: this.password
})
}
}
}
</script>

  • src/api/user.js

export const login = ({ userName, password }) => {
return axios.request({
url: '/index/login',
method: 'post',
data: {
userName,
password
}
})
} export const authorization = () => {
return axios.request({
url: '/users/authorization',
method: 'get'
})
}
  • src/store/module/user.js

import {
login
} from '@/api/user' const actions = {
login ({
commit
}, {
userName,
password
}) {
login({
userName,
password
}).then(res => {
console.log(res) // {code: 200, mes: "success", data: {token: "eyJhbGciOiJIUz"}}
}).catch(error => {
console.log(error)
})
}
}

点击提交成功返回

密码错误返回:

  • src/lib/util.js

import Cookies from 'js-cookie'

// 将Token放在haeder中, 每次发送请求都带有Token
export const setToken = (token, tokenName = 'token') => {
Cookies.set(tokenName, token) // 往cookie中存值
} export const getToken = (tokenName = 'token') => { // 获取Token
return Cookies.get(tokenName)
}
    • store/module/user.js

const actions = {
login({
commit
}, {
userName,
password
}) {
return new Promise(resolve, reject) => {
login({
userName,
password
}).then(res => {
// console.log(res) // {code: 200, mes: "success", data: {token: "eyJhbGciOiJIUz"}}
if (res.code === 200 && res.data.token) {
setToken(res.data.token)
resolve()
} else {
reject(new Error('错误'))
}
}).catch(error => {
reject(error)
})
}
}
}
    • login.vue
    handleSubmit () {
this.login({
userName: this.userName,
password: this.password
}).then(res => {
this.$router.push({
name: 'home'
})
}).catch(error => {
console.log(error)
})
}
}
  • src/router/index.js

路由导航守卫

router.beforeEach((to, from, next) => {
const token = getToken()
if (token) {
// 验证token是有效的
} else {
if (to.name === 'login') next()
else next({ name: 'login' })
}
})
  • 传Token到服务端

    • api/user.js

export const authorization = () => {
return axios.request({
url: '/users/authorization',
method: 'get'
})
}
  • lib/axios.js

传入token

import { getToken } from '@/lib/util'

// 全局响应拦截器
interceptors (instance, url) {
instance.interceptors.request.use(config => { // 请求拦截器
// 添加全局的loading...
// Spin.show() ---遮罩组件
// 队列中有请求时 显示loadong界面, 反之同理
if (!Object.keys(this.queue).length) {
// Spin.show()
}
this.queue[url] = true
config.headers['Authorization'] = getToken() // 传入token
return config
}, error => {
return Promise.reject(error)
})
  • 获取Token

    • store/module/user.js

import {
login,
authorization
} from '@/api/user' authorization({
commit
}, token) {
return new Promise((resolve, reject) => {
authorization().then(res => {
if(parseInt(res.code) === 401){
reject(new Error('token error'))
} else {
resolve()
}
}).catch(error =>{
reject(error)
})
})
}
}
  • router/index.js

import store from '@/store'
import {
getToken,
setToken
} from '@/lib/util' // 导航守卫
router.beforeEach((to, from, next) => {
const token = getToken()
if (token) {
// 验证token是有效的
store.dispatch('authorization', token).then(() => {
if (to.name === 'login') {
next({
name: 'home'
})
} else next()
}).catch(() => {
setToken('')
next({
name: 'login'
})
})
} else {
if (to.name === 'login') next()
else {
next({
name: 'login'
})
}
}
})

3. Token过期处理

api/user.js

authorization ({
commit
}, token) {
return new Promise((resolve, reject) => {
authorization().then(res => {
if (parseInt(res.code) === 401) {
reject(new Error('token error'))
} else {
setToken(res.data.token) // 重置token 即重置过期时间
resolve()
}
}).catch(error => {
reject(error)
})
})
}

4. 退出登录

api/user.js

  logout () {
setToken('')
}
  • 调用登出接口
import { mapActions } from 'vuex'
export default {
methods: {
...map(['logout']),
handleLogout() {
this.logout()
}
}
}

Vue 登录/登出以及JWT认证的更多相关文章

  1. Vue登录登出以及JWT认证

    数据模型 主要用户名,密码,邮箱,头像,身份 const mongoose = require('mongoose') const schema = new mongoose.Schema({ use ...

  2. 利用Vue.js实现登录/登出以及JWT认证

    JSON Web Token 入门教程:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html 后端代码地址:https ...

  3. flask 实现登录 登出 检查登录状态 的两种方法的总结

    这里我是根据两个项目的实际情况做的总结,方法一(来自项目一)的登录用的是用户名(字符串)和密码,前后端不分离,用form表单传递数据:方法二用的是手机号和密码登录,前后端分离,以json格式传递数据, ...

  4. SpringBoot登录登出切面开发

    阅读本文约“2.5分钟” 本文开发环境是SpringBoot2.X版本. 对于系统而言(这里多指管理系统或部分具备登录登出功能的系统),登录登出是一个类权限验证的过程,现在一般是以token进行校验, ...

  5. Struts2学习第六课 实现登录登出功能

    关于Struts2请求的扩展名问题: 1).org.apache.struts2包下的default.properties中配置了struts2应用的一些常量 2).struts.action.ext ...

  6. ThinkPHP---案例1登录登出和添加部门

    配置文件分3类:系统配置文件,分组配置文件,应用配置文件 ①系统配置文件ThinkPHP/Conf/convention.php: ②分组 / 模块 /平台配置文件Home/Conf/config.p ...

  7. ASP.NET Core 登录登出 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 登录登出 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 登录登出 上一章节我们总算完善了注册的功能,而且也添加了一个用户,现 ...

  8. Django项目: 4.用户登录登出功能

    用户登录登出功能 一.功能需求分析 1. 登录退出功能分析 流程图 功能 登录页面 登录功能 退出功能 二.登录页面 1. 接口设计 接口说明 类目 说明 请求方法 GET url定义 /user/l ...

  9. jquery ajax常用的登录登出

    整理jquery+ajax的登录登出方法. //登录 var currentUserId = -1; $(function() { var timestamp = (new Date()).value ...

随机推荐

  1. 性能分析(7)- 未利用系统缓存导致 I/O 缓慢案例

    性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 前提 前面有学到 Buffer 和 Cache 的 ...

  2. 谈谈javascript的基本规范~~~~

    1.不要在同一行声明多个变量. 2.请使用===或==来比较true或false或者数值 3.使用对象字面量代替new Array这种形式 4.不要使用全局函数 5.switch语句必须带有defau ...

  3. 【服务器部署】Django+宝塔+Nginx_uwsgi部署

    :CentOS安装脚本: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install ...

  4. andriod开发中遇到的错误

    1.java.net.UnknownServiceException: CLEARTEXT communication ** not permitted by network security pol ...

  5. 算法-heapq模块优先队列

    heapq模块, 优先队列,小顶堆,最少值放在顶部,值越小,优先级越高 heapq.heappop(heap) 从堆中弹出最小的元素,并重新调整 heapq.heappush(heap, item)新 ...

  6. SpringBoot整合SpringAdmin搭建监控平台

    在SpringBoot整合Actuator进行健康监控中,胜金讲述了通过Actuator进行健康监控,但是学习API并根据API开发前端需要花费相当大的精力,本次胜金就写一下通过SpringAdmin ...

  7. python格式化输出及大量案例

    python格式化输出符号及大量案例 1.格式化输出符号 python格式化输出符号 格式化符号 含义 %c 转化成字符 %r 优先使用repr()函数进行字符串转化 %s 转换成字符串,优先使用st ...

  8. 赫然:怎样学习seo优化技术

    http://www.wocaoseo.com/thread-79-1-1.html 今天的题目是学习SEO起步阶段每个人都要问的.SEO怎么学?如何进阶SEO技能?都包括哪些知识?笔者也自己总结过一 ...

  9. ZooKeeper的十二连问,你顶得了嘛?

    前言 一线大厂ZooKeeper的十二连问,你顶得了嘛? 本文已经收录到github ❝ https://github.com/whx123/JavaHome ❞ 1. 面试官:工作中使用过Zooke ...

  10. Android开发之java代码中获取当前系统的时间工具类

    /** * 获取当前时间 * * @return */ public String getTime() { Date date = new Date();// 创建一个时间对象,获取到当前的时间 Si ...