这里我们先说说登陆以及登陆状态控制需要的插件 jsonwebtoken,jsonwebtoken 就可以实现 token 的生成与反向解密出用户数据. 安装步骤: NPM install jsonwebtoken --save
安装之后先创建一个 token.JS, 为了项目目录的清晰, 可以创建一个 token 文件夹, 将 token.JS 放到里面. 文件创建 OK 之后, 该是写内容了, 写内容之前先说说 jsonwebtoken 提供的方法:
1,sign: 生成 token,2,decod: 解析 token. 这两个方法就是我们常用的加密和解密用的方法.
token.JS 我们先定义两个方法 addtoken(生成 token),decrypt(解析前台传递的 token), 这里直接上代码
token.JS 内容:
- const jwt = require('jsonwebtoken');
- const serect = 'token'; // 生成 token 所需要的密钥
- let token = {
- addToken: (userInfo) => {
- const token = jwt.sign({ // 这个函数需要三个参数, 第一个一般是登陆用户的名字, 第二个就是上面定义的密钥, 第三个是过期时间 单位是 s , 不过还可以写 {expiresIn:'2h'}(代表 2 小时)
- user: userInfo.user,
- id: userInfo.id
- }, serect, {expiresIn: 1});
- return token;
- },
- decrypt: (token) => {
- if (token) {
- let toke = tokens.split(' ')[1];
- // 解析
- let decoded = jwt.decode(toke, serect); // 解析 token 需要两个参数, 密钥 以及 前台传递的 token
- return decoded;
- }
- }
- }
- exports = module.exports = token;
然后修改登陆接口, 登陆之后要将生成的 token 传递给前台, 直接看代码:
- const addToken = require('../token/token')
- router.post('/login',async (ctx)=> {
- let username = ctx.request.body.username;
- let password = ctx.request.body.password
- await userModel.selectUser([username]).then(async res => {
- if (res.length === 0) {
- ctx.body = {
- code: 102,
- message: '对不起账号不存在'
- }
- } else {
- if (await md5.MD5(password,res[0].solt) === res[0].password) {
- const token = addToken.addToken({user: res[0].name, id: res[0].id}) // 主要是这里 生成 token
- ctx.body = {
- code: 100,
- message: '登陆成功',
- token
- }
- } else {
- ctx.body = {
- code: 101,
- message: '对不起密码错误'
- }
- }
- }
- })
- })
后台传递的 token 值, 前台需要保存, 我们使用的 vue 所以可以使用 vuex 将收到的 token 保存起来(这里提示 vuex 当页面刷新里面的数据会清除, 所以建议保存在 localStorage 里面当然也可以使用 vuex-along 这个组件, 这个组件其实就是帮我们把 vuex 的数据再保存在 loaclStorage 里面)
- axios.post('/api/login', user).then(({status, data}) => {
- if (status === 200) {
- if (data.code === 102) {
- alert('对不起账号不存在')
- } else if (data.code === 101) {
- alert('对不起密码不正确')
- } else if (data.code === 100) {
- alert('登陆成功')
- console.log(data)
- this.$store.dispatch('tokenAddFun', data.token)
- this.$store.dispatch('userAddFun', user.username)
- this.$router.push('/')
- }
- }
- })
然后在每次请求的时候将 token 添加在请求的头信息中: 我们使用的是 axios, 所以可以使用 axios 的请求拦截器, 修改其头头信息, 这样就不用在每个请求中添加. 添加 axios 目录然后添加 axios.JS 文件, 内容如下:
- import axios from 'axios'
- import store from '../store'
- axios.interceptors.request.use(
- config => {
- config.headers.common['Authorization'] = 'Bearer'+ store.state.token;
- return config
- }
- )
- export default axios
需要请求的时候 导入自己写的这个 JS 文件 (导入自己写的这个文件之后就不需要导入 axios 插件了) 测试请求代码如下:
- import axios from '../../../axios/axios'
- axios.get('/api/userlist').then(({status, data}) => {
- if (status === 200) {
- if (data.code !== 100) {
- alert('对不起, session 过期, 请重新登陆');
- this.$router.push('/login')
- } else {
- this.showData()
- }
- }
- })
后台 koa2 接收到请求之后先对请求头携带 token 进行解析, 然后对比是否过期, 具体代码如下:
- const token = require('../token/addtoken')
- router.get('/userlist', async (ctx, next) => {
- let webToken = ctx.request.header.authorization; // 获取头部信息携带的 token
- if (webToken){
- // 获取到 token
- let res = token.decrypt(webToken); // 解析 token
- if (res && res.exp <= new Date()/1000){ // 进行时间对比
- ctx.body = {
- message: 'token 过期',
- code:102
- };
- } else {
- ctx.body = {
- message: '解析成功',
- code:100
- }
- }
- } else{ // 没有取到 token
- ctx.body = {
- msg:'没有 token',
- code: 101
- }
- }
- })
后台通过上述的方法, 将数据以及登陆状态传递给前台, 前台进行逻辑判断 就可以实现登陆状态的判断
以上是自己实现登陆状态判断的一个小例子, 如果有不正确的地方, 麻烦留言提醒, 谢谢
来源: https://www.cnblogs.com/webtaotao/p/11356162.html