这篇文章分享一下本人学习vue+node.js前后端交互中的登录token令牌的心得
最近准备写一个个人博客网站,前端采用的是vue+element,后端用node.js
在做用户登录的时候就想到
如果不给每个页面进行用户登录状态判断的话,是不是就可以直接跳过登录进行操作呢?
显然如果让用户跳过登录直接进行网站的功能操作是不可行的
于是就在网上查资料,最后想到了用token令牌验证的方法
那咱们直接进入正题
一、前端登录时向后端发起请求,并携带登录信息
原理:前端发起登录请求,将登录信息(可以是账号密码)存入请求头header的Authorization中,后端接收Authorization中的信息进行解析
为了方便前端接口的书写,我使用了axios进行请求的封装
1:在vue项目中的main.js中引入axios
import axios from 'axios'
如果你没有下载axios(如果是创建的vue项目的话,基本都会下载axios吧 0.0)
在vue项目中打开控制台
npm install axios -s
下载完之后,同上在vue项目中的main.js中引入axios
2.挂载axios原型
在main.js中写这个,将$http挂载为axios原型
Vue.prototype.$http=axios
3.向后端发起请求
怎么发起请求都不重要!只要你能成功发起请求就可以
this.$http.post('/userLogin',this.loginForm)
我用的是异步请求
const {data: res} = await this.$http.post('/userLogin',this.loginForm)
console.log(res)
二、后端接收登录请求,判断用户id后给responce添加token令牌并发送给前端
这里要注意一下,后端必须添加以下字段,不然会有跨域错误!
res.header中的Authorization一定要设置,不然接不到前端发来的token
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*') //允许所有不同源的地址访问
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization') //Content-Type必须要设置,Authorization是用户登录注册时存入的token值,可根据需求来设置,还有其他的都需要用逗号隔开
res.header('Access-Control-Allow-Credentials', true) // 这个必须要设置,否则解决跨域无效,注意true是字符串
next()
})
1、后端接到前端的账号密码之后,从数据库中判断账号密码的正确性
我这里用的是mysql,账号密码的校验这里不做解释
const sql =`select UserName,Sex,UserId from user where UserId='${JSON.parse(DATA).userId}' and PassWord ='${JSON.parse(DATA).passWord}'`
2.给响应添加token
这里需要安装一个token模块 jsonwebtoken
2.1 安装jsonwebtoken模块并简单配置
在终端安装模块
npm install jsonwebtoken
创建一个js文件
然后简单封装配置,并把js文件expors出去
const jwt = require('jsonwebtoken');
const token = {
encrypt:function(data,time){
return jwt.sign(data,'token',{expiresIn:time})
},
decrypt:function(token){
try{
let data = jwt.verify(token,'token');
console.log("data",data);
return{
token:true,
id:data.id
};
} catch(e){
return{
token:false,
data:e
}
}
}
}
module.exports = {token}
在login.js中导入文件
const {token} = require('../Tools/token')
注意上方的路径是你自己项目中token.js的路径
2.2 根据登录用户的id,为此id添加token密钥
使用token.excrypt方法需要传递两个参数,一个为数据,我这里用的是用户id(必须为对象格式),一个是token失效时间,这里是15天
最后会生成一个密钥,你可以自己试试,每个密钥都可以通过解密转换成用户的id,供以后后端进行验证
let Token =token.encrypt({id:JSON.parse(DATA).userId},'15d')
下面是我自己的代码,目的是生成token后,将token与用户信息一起传给前端
req.on("data",async function(DATA){
const sql =`select UserName,Sex,UserId from user where UserId='${JSON.parse(DATA).userId}' and PassWord ='${JSON.parse(DATA).passWord}'`
console.log( JSON.parse(DATA).userId);
let userInfo =await exec(sql)
console.log("userid",JSON.parse(DATA).userId);
//发送给前端的数据
let User={}
//发送给前端的data数据 包含token等
let data={}
//发送给前端的meta数据 包含status msg等
let meta={}
if(userInfo.length>0){
let Token =token.encrypt({id:JSON.parse(DATA).userId},'15d')
for(var item in userInfo){
data['Token'] = Token
data['userInfo'] = userInfo[item]}
meta['status'] = 201
meta['msg'] = '登录成功!'
User['data']=data
User['meta']=meta
res.send(User)
}else{
meta['status'] = 200
meta['msg'] = '登录失败!'
User['meta']=meta
res.send(User)
}
})
三、前端发送登录请求后接收到后端传来用户信息以及token,将token存入storage中
1
将token存入名为Token的storage中,供以后调用
window.sessionStorage.setItem('Token', res.data.Token)
2 在vue main.js中通过axios拦截器添加token,使每次请求都能将token传给后端
这样做的话,每次请求都会将token发给后端,后端接到token后将其解密,可以判断当前用户是否处于登陆状态
//在连接端口之前,通过axios拦截器添加token,保证拥有获取数据的权限.
axios.interceptors.request.use(config=>{
//console.log(config);
//为请求头对象添加token验证的Authorization字段
config.headers.Authorization=window.sessionStorage.getItem('Token')
console.log(config.headers.Authorization);
return config
})
四、后端获取token并解密
在后端的接口函数中判断请求头中的authorization 是否存在,如果不存在,则证明用户没有登陆,如果存在,就可以进行进一步操作
token.decrypt可以对加密的token进行解密,得到用户的id
if(req.headers.authorization == 'null'){
console.log("您没有权限!");
res.send("您没有权限!")
}else{
let tokenData = token.decrypt(req.headers.authorization)
console.log(tokenData);
let sql =`select TITLE,BLOG_ID,TIME from blog where AUTHOR_ID=${tokenData.id}`
let userInfo =await exec(sql)
console.log(JSON.stringify(userInfo));
res.send(userInfo)
}
得到用户的id后就说明用户处于登录状态,就可以进行其他的操作啦!