1. 数据库创建
用Navicat创建一个数据库“db”,在创建一张存储用户登录信息的表,命名为“demo-admin”,
表的设计如下(表直接拿“hioshop”开源项目中的admin表):
hioshop-server
id |
username |
password |
password_salt |
last_login_ip |
last_login_time |
is_delete |
14 |
hiolabs |
4af5d2d0e6c2bd03dca28c884afdf0ee |
HIOLABS |
|
|
|
2. 创建一个thinkjs项目
thinkjs new demo-server
3. 配置项目数据库
找到项目‘src/config/adapter.js’文件,打开这个文件,修改代码如下:
mysql: {
handle: mysql,
database: 'db',
prefix: 'demo_',
encoding: 'utf8mb4',
host: '127.0.0.1',
port: '3306',
user: 'root',
password: '123123123',
dateStrings: true
}
4. 用户的登录验证实现
thinkjs controller auth
thinkjs service token
假设客户端向服务端发送一个post请求携带用户名和密码的请求‘/auth/login’接口,服务端对当前
请求进行验证,验证通过则往下继续执行,相关验证代码如下:
const Base = require('./base.js');
module.exports = class extends Base {
async loginAction(){
const username = this.post('username');
const password = this.post('password');
const admin = await this.model('admin').where({
username:username}).find();
if(think.isEmpty(admin)){
return this.fail(401,'用户名不正确');
}
if(think.md5(password + '' + admin.password_salt) !== admin.password){
return this.fail(401,'用户密码错误');
}
await this.model('admin').where({
id:admin.id}).update({
last_login_time:parseInt(Date.now()/1000),
last_login_ip:this.ctx.ip
});
const TokenService = this.service('token');
const token = await TokenService.create({
id:admin.id
});
if(think.isEmpty(token)){
return this.fail('用户登录失败');
}
const userInfo = {
id:admin.id,
username:admin.username
};
return this.success({
token:token,
userInfo:userInfo
});
}
};
const jwt = require('jsonwebtoken');
const secret = '&w@ueJnXy!Gj0J@qVmMPR^9ip00EP0^Qy5Se#lzwStExJ3Zw4j02NVLm^btjBO8x'
module.exports = class extends think.Service {
async create(userId){
const token = jwt.sign(userId,secret);
return token;
}
async parse(){
if(think.isEmpty(think.token)){
return null;
}
else{
try{
return jwt.verify(think.token,secret).id;
}catch(err){
return null;
}
}
}
};
通过以上操作后端接口‘auth/login’将token返回给客户端,假设客户端获取到服务端响应的token,
把token值存储在header请求头'Authorization'中,便于每次请求路由时携带token发送到服务端
接着实现对每次请求的token验证是否合法的实现,代码如下:
module.exports = class extends think.Controller {
async _before(){
think.token = this.ctx.header['Authorization'] || '';
const Token = this.service('token');
think.userId = await Token.parse();
if(this.ctx.controller !== 'auth'){
if(think.isEmpty(think.userId)){
return this.fail('用户未登录');
}
}
}
};