On this page
用户登录
jwt 加密鉴权 插件地址:
安装
shell
npm i egg-jwt --save
配置
js
// {app_root}/config/plugin.js
exports.jwt = {
enable: true,
package: "egg-jwt",
};
// {app_root}/config/config.default.js
config.jwt = {
secret: "qhdgw@45ncashdaksh2!#@3nxjdas*_672",
};
安装crypto模块
shell
npm i crypto --save
js
// app/extend/context.js
// 引入模块
const crypto = require('crypto');
// 生成token
getToken(value) {
return this.app.jwt.sign(value, this.app.config.jwt.secret);
},
// 验证token
checkToken(token) {
return this.app.jwt.verify(token, this.app.config.jwt.secret);
},
// 验证密码
async checkPassword(password, hash_password) {
// 先对需要验证的密码进行加密
const hmac = crypto.createHash("sha256", this.app.config.crypto.secret);
hmac.update(password);
password = hmac.digest("hex");
let res = password === hash_password;
if (!res) {
this.throw(400, '密码错误');
}
return true;
}
redis 缓存插件和封装 安装
shell
npm i egg-redis --save
配置
js
// config/plugin.js
exports.redis = {
enable: true,
package: "egg-redis",
};
// redis存储
config.redis = {
client: {
port: 6379, // Redis port
host: "127.0.0.1", // Redis host
password: "",
db: 2,
},
};
缓存库封装
js
// app/service/cache.js
"use strict";
const Service = require("egg").Service;
class CacheService extends Service {
/**
* 获取列表
* @param {string} key 键
* @param {boolean} isChildObject 元素是否为对象
* @return { array } 返回数组
*/
async getList(key, isChildObject = false) {
const { redis } = this.app;
let data = await redis.lrange(key, 0, -1);
if (isChildObject) {
data = data.map((item) => {
return JSON.parse(item);
});
}
return data;
}
/**
* 设置列表
* @param {string} key 键
* @param {object|string} value 值
* @param {string} type 类型:push和unshift
* @param {Number} expir 过期时间 单位秒
* @return { Number } 返回索引
*/
async setList(key, value, type = "push", expir = 0) {
const { redis } = this.app;
if (expir > 0) {
await redis.expire(key, expir);
}
if (typeof value === "object") {
value = JSON.stringify(value);
}
if (type === "push") {
return await redis.rpush(key, value);
}
return await redis.lpush(key, value);
}
/**
* 设置 redis 缓存
* @param { String } key 键
* @param {String | Object | array} value 值
* @param { Number } expir 过期时间 单位秒
* @return { String } 返回成功字符串OK
*/
async set(key, value, expir = 0) {
const { redis } = this.app;
if (expir === 0) {
return await redis.set(key, JSON.stringify(value));
} else {
return await redis.set(key, JSON.stringify(value), "EX", expir);
}
}
/**
* 获取 redis 缓存
* @param { String } key 键
* @return { String | array | Object } 返回获取的数据
*/
async get(key) {
const { redis } = this.app;
const result = await redis.get(key);
return JSON.parse(result);
}
/**
* redis 自增
* @param { String } key 键
* @param { Number } value 自增的值
* @return { Number } 返回递增值
*/
async incr(key, number = 1) {
const { redis } = this.app;
if (number === 1) {
return await redis.incr(key);
} else {
return await redis.incrby(key, number);
}
}
/**
* 查询长度
* @param { String } key
* @return { Number } 返回数据长度
*/
async strlen(key) {
const { redis } = this.app;
return await redis.strlen(key);
}
/**
* 删除指定key
* @param {String} key
*/
async remove(key) {
const { redis } = this.app;
return await redis.del(key);
}
/**
* 清空缓存
*/
async clear() {
return await this.app.redis.flushall();
}
}
module.exports = CacheService;
控制器:app/controller/api/user.js
js
// 登录
async login() {
const { ctx, app } = this;
// 参数验证
ctx.validate({
username: {
type: 'string',
required: true,
desc: '用户名'
},
password: {
type: 'string',
required: true,
desc: '密码'
},
});
let { username, password } = ctx.request.body;
// 验证该用户是否存在|验证该用户状态是否启用
let user = await app.model.User.findOne({
where: {
username,
}
});
if (!user) {
ctx.throw(400, '用户不存在或已被禁用');
}
// 验证密码
await ctx.checkPassword(password, user.password);
user = JSON.parse(JSON.stringify(user));
// 生成token
let token = ctx.getToken(user);
user.token = token;
delete user.password;
// 加入缓存中
if (!await this.service.cache.set('user_' + user.id, token)) {
ctx.throw(400, '登录失败');
}
// 返回用户信息和token
return ctx.apiSuccess(user);
}
路由:app/router.js
js
// 用户登录
router.post("/api/login", controller.api.user.login);