隐藏
前端Token生成 | 奔跑吧!代码

前端Token生成

最近在做数据库课程设计,我是做前端的,后端并不是很懂,看vue这个框架仅仅只是入门,所以这篇文章写的可能不怎么好,仅作记录,有什么不对或不足的地方欢迎大神指出。

问题

做一个登录界面,我选择的是用token进行验证登录,我用的前端框架是Vue.js 和 element-ui,如何在vue 中使用token进行验证登录

思考

1、利用token进行验证登录,用户进行登录操作时,后台会生成一个token返回给前端,由前端 将这个token放到请求头中(这个是百度的,一般都是放在请求头),并且此后调用接口都要把token放到请求的请求头传回给后台。
2、用户登录后,前端需要把token保存下来,后面发送请求的时候在拿出来;
3、在发送每个请求时都要把token加到请求头里,写一个全局的拦截器

记录和说明

使用vuex存储登录状态并用cookie存储token

在src文件夹(我的vue项目是用vue-cli 脚手架创建的)下创建一个store文件夹,在store中创建一个index.js

src/store/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import app from './modules/app'
import chat from './modules/chat'
import getters from './getters'

//用sessionStorage使vuex持久化,保存至本次回话结束,防止刷新导致前端反复向后端请求数据
const handleStore = store => {
if (sessionStorage.store) store.replaceState(JSON.parse(sessionStorage.store)) // 初始化store
store.subscribe((mutation, state) => {
sessionStorage.setItem("store", JSON.stringify(state))
})
}

Vue.use(Vuex)

const store = new Vuex.Store({
modules: {
chat,
app,
user,
},
getters,
plugins: [handleStore]
})

export default store

src/store/module/user.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { loginById,loginByToken, logout, getUserInfo,checkSession,changePassword, register} from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import {setSecret,changePasswordBySecret,checkHaveSecret} from "@/api/security";
import {baseUrl} from "@/api";
import {editUser} from "@/api/admin";

const defaultAvatar=baseUrl+'/UserAvatar/default_avatar.png'

const user = {
state: {
id: '',
token: getToken('token'),
name: '',
sex:'',
phone:'',
loc:'',
role: '',
avatar: '',
brandId:'',
status: false,
secretStatus:false
},

mutations: {
SET_USER:(state,info)=>{
if(info.role==='normal'){
state.id=info.data.id
state.name = info.data.name===null?"User":info.data.name
state.sex = info.data.sex
state.loc = info.data.loc
state.avatar = info.data.avatar===null?defaultAvatar:baseUrl+info.data.avatar
}
else if(info.role==='admin' || info.role==='superAdmin'){
state.id = info.data.shopId
state.name = info.data.shopName===null?"admin":info.data.shopName
state.brandId=info.data.brand.brandId
state.avatar = info.data.brand.logo===null?defaultAvatar:baseUrl+info.data.brand.logo
}
state.token = info.data.token
state.phone = info.data.phone
state.role = info.role
state.status = true
},
CLEAR_USER:(state)=>{
state.id=''
state.token = ''
state.name = ''
state.sex = ''
state.phone = ''
state.loc = ''
state.role = ''
state.avatar = ''
state.status = false
state.brandId = ''
}
},

actions: {
//用户信息状态初始化
UserInfoInit({commit}){
return new Promise(resolve => {
commit('CLEAR_USER')
resolve()
})
},
// 用户名登录
loginById({ commit }, loginInfo) {
const id = loginInfo.id.trim()
return new Promise((resolve, reject) => {
loginById(id, loginInfo.encryptPassword,loginInfo.role).then(data => {
if(data.code===401)
reject("用户名或密码错误")
else if(data.code===402)
reject("用户名不存在")
else if(data.code===400){
if(data.role==='admin'||data.role==='superAdmin')
commit('SET_SECRET_STATUS',true)
else {
checkHaveSecret(id).then(response=>{
commit('SET_SECRET_STATUS',response==='success')
})
}
commit('SET_USER',data)
setToken('token',data.data.token)
if(loginInfo.radio==='1'){
setToken('id',id)
setToken('password',loginInfo.password)
setToken('role',loginInfo.role)
}else{
removeToken('id')
removeToken('password')
removeToken('role')
}
}
resolve()
}).catch(error => {
reject(error)
})
})
}
}
}

export default user

说明:
(1)在写src/store/index.js 里的内容之前,要在你的项目里安装Vuex ,这里只提供npm的安装方法,在项目根目录处打开cmd 输入下面的命令,后回车

npm install vuex --save

(2) 在这个store/store/index.js中 这段代码setTokenremoveToken这两个函数源码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Cookies from 'js-cookie'
import {encryptMd5} from '@/utils/encrypt'

/*const TokenKey = 'Admin-Token'*/

export function getToken(TokenKey) {
return Cookies.get(TokenKey)
}

export function setToken(TokenKey,token) {
if(TokenKey==='token')
return Cookies.set(TokenKey, token,{ expires:1 })
else
return Cookies.set(TokenKey, token,{expires:3})
}

export function removeToken(TonkenKey) {
return Cookies.remove(TonkenKey)
}

定义全局拦截器和Ajax请求对象

src/main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import axios from 'axios'
import { Message,MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { baseUrl } from '@/api'

const tokenBlankList=['/user/register','/car/get']
// 创建axios实例
const service = axios.create({
baseURL: baseUrl, // api 的 base_url=”http://localhost:8080“
timeout: 5000 // request timeout
})

// request拦截器
service.interceptors.request.use(
config => {
// 发送请求时添加配置信息
if(config.headers['Content-Type']==='application/json')
config.data = JSON.stringify(config.data);
if (tokenBlankList.indexOf(config.url)===-1&&getToken('token')&&typeof(getToken('token'))!=="undefined") {
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
config.headers['Token'] = getToken('token')
}
return config
},
error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)

// response拦截器
service.interceptors.response.use(
/**
* 下面的注释为通过在response里,自定义code来标示请求状态
* 当code返回如下情况则说明权限有问题,登出并返回到登录页
* 如想通过 xmlhttprequest 来状态码标识 逻辑可写在下面error中
* 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除
*/
response => {
const res = response.data
//404:非法的token; 403:其他客户端登录了; 50014:Token 过期了;
if (res.code === 404 || res.code === 403 || res.code === 402) {
//请自行在引入 MessageBox
//import { Message, MessageBox } from 'element-ui'
MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('FedLogOut').then(() => {
location.reload() //为了重新实例化vue-router对象 避免bug
})
})
return Promise.reject('error')
} else if(res.code===400) {
return res.datas
}
},
error => {
console.log(error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)

export default service

说明

这个是全部的代码,不一定都和这个一样,下面说说用token验证,src/main.js中要配置那些东西
说明

具体前端代码

src/components/login.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
onLogin(){
//数据格式验证完毕,实现登录功能
if(!this.$refs.Verity.isPassing){
this.$message.error({
message:"验证失败,请拉拽到右边以验证",
showClose:true
});
return
}else{
this.loginForm.encryptPassword=encryptMd5(this.loginForm.password)
this.$store.dispatch('loginById', this.loginForm).catch((err) => {
this.$message.error({
message:err,/*"登录失败,请检查后重试"*/
showClose:true
})
})
}
this.props.show=false;
}

具体源代码详见Github

Github-CarShop

---------------- The End ----------------

本文标题:前端Token生成

文章作者:lamprose

发布时间:2019年03月30日 - 15:36

最后更新:2019年06月03日 - 18:02

原始链接:https://lamprose.github.io/development/vue-token/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!