Ver código fonte

fix 修复微信登录

tumobi 7 anos atrás
pai
commit
2359b45d88
3 arquivos alterados com 50 adições e 10 exclusões
  1. 16 9
      src/api/controller/auth.js
  2. 29 0
      src/api/service/weixin.js
  3. 5 1
      src/common/config/config.js

+ 16 - 9
src/api/controller/auth.js

@@ -9,7 +9,6 @@ module.exports = class extends Base {
    */
   async indexAction() {
     const avatarPath = think.RESOURCE_PATH + '/static/user/avatar/1.' + _.last(_.split('https://img6.bdstatic.com/img/image/smallpic/liutaoxiaotu.jpg', '.'));
-    // rp('https://img6.bdstatic.com/img/image/smallpic/liutaoxiaotu.jpg').pipe(fs.createWriteStream(avatar_path));
     return this.success(avatarPath);
   }
 
@@ -17,6 +16,7 @@ module.exports = class extends Base {
     const code = this.post('code');
     const fullUserInfo = this.post('userInfo');
     const userInfo = fullUserInfo.userInfo;
+    const clientIp = ''; // 暂时不记录 ip
 
     // 获取openid
     const options = {
@@ -25,13 +25,12 @@ module.exports = class extends Base {
       qs: {
         grant_type: 'authorization_code',
         js_code: code,
-        secret: '00a2749d6f15e1979194d80b777e6adf',
-        appid: 'wx262f4ac3b1c477dd'
+        secret: think.config('weixin.secret'),
+        appid: think.config('weixin.appid')
       }
     };
 
     let sessionData = await rp(options);
-
     sessionData = JSON.parse(sessionData);
     if (!sessionData.openid) {
       return this.fail('登录失败');
@@ -44,6 +43,13 @@ module.exports = class extends Base {
       return this.fail('登录失败');
     }
 
+    //  析用户数据
+    const WeixinSerivce = this.service('weixin', 'api');
+    const weixinUserInfo = await WeixinSerivce.decryptUserInfoData(sessionData.session_key, fullUserInfo.encryptedData, fullUserInfo.iv);
+    if (think.isEmpty(weixinUserInfo)) {
+      return this.fail('登录失败');
+    }
+
     // 根据openid查找用户是否已经注册
     let userId = await this.model('user').where({ weixin_openid: sessionData.openid }).getField('id', true);
     if (think.isEmpty(userId)) {
@@ -52,12 +58,13 @@ module.exports = class extends Base {
         username: '微信用户' + think.uuid(6),
         password: sessionData.openid,
         register_time: parseInt(new Date().getTime() / 1000),
-        register_ip: this.ctx.ip,
+        register_ip: clientIp,
         last_login_time: parseInt(new Date().getTime() / 1000),
-        last_login_ip: this.ctx.ip,
+        last_login_ip: clientIp,
+        mobile: '',
         weixin_openid: sessionData.openid,
-        avatar: userInfo.avatarUrl,
-        gender: userInfo.gender, // 性别 0:未知、1:男、2:女
+        avatar: userInfo.avatarUrl || '',
+        gender: userInfo.gender || 1, // 性别 0:未知、1:男、2:女
         nickname: userInfo.nickName
       });
     }
@@ -70,7 +77,7 @@ module.exports = class extends Base {
     // 更新登录信息
     userId = await this.model('user').where({ id: userId }).update({
       last_login_time: parseInt(new Date().getTime() / 1000),
-      last_login_ip: this.ctx.ip
+      last_login_ip: clientIp
     });
 
     const TokenSerivce = this.service('token', 'api');

+ 29 - 0
src/api/service/weixin.js

@@ -0,0 +1,29 @@
+const crypto = require('crypto');
+
+module.exports = class extends think.Service {
+  async decryptUserInfoData(sessionKey, encryptedData, iv) {
+    // base64 decode
+    const _sessionKey = new Buffer(sessionKey, 'base64');
+    encryptedData = new Buffer(encryptedData, 'base64');
+    iv = new Buffer(iv, 'base64');
+    let decoded = '';
+    try {
+      // 解密
+      const decipher = crypto.createDecipheriv('aes-128-cbc', _sessionKey, iv);
+      // 设置自动 padding 为 true,删除填充补位
+      decipher.setAutoPadding(true);
+      decoded = decipher.update(encryptedData, 'binary', 'utf8');
+      decoded += decipher.final('utf8');
+
+      decoded = JSON.parse(decoded);
+    } catch (err) {
+      return '';
+    }
+
+    if (decoded.watermark.appid !== think.config('weixin.appid')) {
+      return '';
+    }
+
+    return decoded;
+  }
+};

+ 5 - 1
src/common/config/config.js

@@ -1,4 +1,8 @@
 // default config
 module.exports = {
-  default_module: 'api'
+  default_module: 'api',
+  weixin: {
+    secret: '',
+    appid: ''
+  }
 };