Skip to content
关注公众号,获取新课通知

用户登录


jwt 加密鉴权 插件地址:

https://www.npmjs.com/package/egg-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);