鉴权过程
在实现登录接口时,我们先了解一下大致的鉴权过程:
用户输入账号密码调用登录接口发起请求
服务端通过 egg-jwt 插件,结合自定义的加密字符串,生成一个 token 令牌
然后,接口响应返回 token
网页端获取到 token 之后,需要将其存在浏览器本地
之后每次发起请求,无论是获取数据,还是提交数据,都需要将 token 带上,用来标识
比如发起接口请求账单数据
服务端通过 egg-jwt 插件解密 token
解密之后就可以拿到用户信息,从而去查找用户的账单数据
然后,接口响应返回对应的账单数据
准备 egg-jwt 插件
安装 egg-jwt 插件
npm i egg-jwt -S
使用方法可以参考:https://github.com/okoala/egg-jwt#readme
配置 egg-jwt 插件
1、在 config/plugin.js
下添加插件:
jwt: { enable: true, package: 'egg-jwt' }
2、在 config/config.default.js
下添加自定义加密字符串
// jwt 配置 config.jwt = { secret: 'kaimo313', // 自定义加密字符串,secret 是在服务端的,不要泄露 };
实现登录接口
1、简单逻辑校验
在 /controller/user.js
下新建 login 方法,需要判断有没有该用户;找到用户,判断密码是否输入正确
// 登录 async login() { try { const { ctx, app } = this; // 获取登录时的 username, password const { username, password } = ctx.request.body; // 根据用户名,在数据库查找相对应的id操作 const userInfo = await ctx.service.user.getUserByName(username); // 1、没找到说明没有该用户 if (!userInfo || !userInfo.id) { ctx.body = { status: 500, desc: '账号不存在', data: null } return } // 2、找到用户,并且判断输入密码与数据库中用户密码 if (userInfo && password != userInfo.password) { ctx.body = { status: 500, desc: '账号密码错误', data: null } return } } catch (error) { ctx.body = { status: 500, desc: '登录失败', data: null } } }
2、egg-jwt 怎么生成 token
github 网站 https://github.com/okoala/egg-jwt,找到 How To Create A Token
生成 token 之后,在返回给客户端
const token = app.jwt.sign({ id: userInfo.id, username: userInfo.username, exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60) // token 有效期为 24 小时 }, app.config.jwt.secret); // 返回 token ctx.body = { status: 200, desc: '登录成功', data: { token } };
3、添加登录路由
在路由 router.js 脚本中添加:
'use strict'; /** * @param {Egg.Application} app - egg application */ module.exports = app => { const { router, controller } = app; // 注册路由 router.post('/api/user/register', controller.user.register); // 登录路由 router.post('/api/user/login', controller.user.login); };
4、测试登录接口
用 Postman 去测试一下接口是否可行,这里我才用 Apifox 去测试,后面我在单独出一篇介绍一下怎么用 Apifox 生成接口文档。如果登录接口调用成功,效果如下:
{ "status": 200, "desc": "登录成功", "data": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwidXNlcm5hbWUiOiJrYWltbzMxMyIsImV4cCI6MTY0MjU5NTc2MywiaWF0IjoxNjQyNTA5MzYzfQ.BZuaRvEU7_SuqtMU8OtR5fRsa5QSSm0x26i4ZfWwGO0" } }