|
@@ -6,6 +6,7 @@ const { ObjectId } = require('mongoose').Types;
|
|
|
const { CrudService } = require('naf-framework-mongoose/lib/service');
|
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
|
const jwt = require('jsonwebtoken');
|
|
|
+const uuid = require('uuid');
|
|
|
|
|
|
class LoginService extends CrudService {
|
|
|
constructor(ctx) {
|
|
@@ -66,27 +67,76 @@ class LoginService extends CrudService {
|
|
|
}
|
|
|
|
|
|
async wxlogin(data) {
|
|
|
- const { openid } = data;
|
|
|
+ const { qrcode, openid } = data;
|
|
|
+ assert(qrcode, 'qrcode不能为空');
|
|
|
assert(openid, 'openid不能为空');
|
|
|
+ const key = `naf:qrcode:login:${qrcode}`;
|
|
|
+ const status = await this.app.redis.get(key);
|
|
|
+ if (!status) {
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码已过期');
|
|
|
+ }
|
|
|
+ if (status !== 'pending') {
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码状态无效');
|
|
|
+ }
|
|
|
const res = await this.uModel.findOne({ openid });
|
|
|
if (!res) {
|
|
|
throw new BusinessError(ErrorCode.USER_NOT_EXIST);
|
|
|
}
|
|
|
const result = await this.createJwt(res);
|
|
|
+ // TODO: 修改二维码状态,登录凭证保存到redis
|
|
|
+ await this.app.redis.set(key, `scaned:${result}`, 'EX', 600);
|
|
|
+ // TODO: 发布扫码成功消息
|
|
|
const { mq } = this.ctx;
|
|
|
+ const ex = 'qrcode.login';
|
|
|
if (mq) {
|
|
|
- const msg = res.name + '微信登录成功';
|
|
|
- const parm = {
|
|
|
- durable: true,
|
|
|
- headers: {
|
|
|
- token: result,
|
|
|
- } };
|
|
|
- console.log(parm);
|
|
|
- console.log(msg);
|
|
|
- await mq.topic('wx_login', res.id, msg, parm);
|
|
|
- } else {
|
|
|
- this.ctx.logger.error('!!!!!!没有配置MQ插件!!!!!!');
|
|
|
+ await mq.topic(ex, qrcode, 'scaned', { durable: true });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建二维码
|
|
|
+ * 随机生成二维码,并保存在Redis中,状态初始为pending
|
|
|
+ * 状态描述:
|
|
|
+ * pending - 等待扫码
|
|
|
+ * consumed - 使用二维码登录完成
|
|
|
+ * ${jwt.token} - Jwt登录凭证
|
|
|
+ */
|
|
|
+ async createQrcode() {
|
|
|
+ const qrcode = uuid();
|
|
|
+ const key = `naf:qrcode:login:${qrcode}`;
|
|
|
+ await this.app.redis.set(key, 'pending', 'EX', 600);
|
|
|
+ return qrcode;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用二维码换取登录凭证
|
|
|
+ async qrcodeLogin(qrcode) {
|
|
|
+ assert(qrcode, 'qrcode不能为空');
|
|
|
+ const key = `naf:qrcode:login:${qrcode}`;
|
|
|
+ const val = await this.app.redis.get(key);
|
|
|
+ if (!val) {
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码已过期');
|
|
|
+ }
|
|
|
+ const [ status, token ] = val.split(':', 2);
|
|
|
+ if (status !== 'scaned' || !token) {
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码状态无效');
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: 修改二维码状态
|
|
|
+ await this.app.redis.set(key, 'consumed', 'EX', 600);
|
|
|
+
|
|
|
+ return { token };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查二维码状态
|
|
|
+ async checkQrcode(qrcode) {
|
|
|
+ assert(qrcode, 'qrcode不能为空');
|
|
|
+ const key = `naf:qrcode:login:${qrcode}`;
|
|
|
+ const val = await this.app.redis.get(key);
|
|
|
+ if (!val) {
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码已过期');
|
|
|
}
|
|
|
+ const [ status ] = val.split(':', 2);
|
|
|
+ return { status };
|
|
|
}
|
|
|
}
|
|
|
module.exports = LoginService;
|