Skip to content

support miniprogram like wechat-oauth #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 103 additions & 5 deletions lib/oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const httpx = require('httpx');

const querystring = require('querystring');


const WxBizDataCrypt = require('wechat-oauth/lib/wx_biz_data_crypt');

class AccessToken {
constructor(data) {
this.data = data;
Expand Down Expand Up @@ -39,11 +42,13 @@ class AccessToken {
* @param {String} appsecret 在公众平台上申请得到的app secret
* @param {Generator} getToken 用于获取token的方法
* @param {Generator} saveToken 用于保存token的方法
* @param {Boolean} isMiniProgram 是否是微信小程序
*/
class OAuth {
constructor(appid, appsecret, getToken, saveToken) {
constructor(appid, appsecret, getToken, saveToken, isMiniProgram) {
this.appid = appid;
this.appsecret = appsecret;
this.isMiniProgram = isMiniProgram;
// token的获取和存储
this.store = {};
this.getToken = getToken || async function (openid) {
Expand Down Expand Up @@ -201,6 +206,47 @@ class OAuth {
return this.processToken(data);
}

/**
* 根据授权获取到的code,换取小程序的session key和openid(以及有条件下的unionid)
* 获取openid之后,可以调用`wechat.API`来获取更多信息
* Examples:
* ```
* await api.getSessionKey(code);
* ```
* Exception:
*
* - `err`, 获取session key出现异常时的异常对象
*
* 返回值:
* ```
* {
* data: {
* "session_key": "SESSION_KEY",
* "openid": "OPENID",
* "unionid": "UNIONID"
* }
* }
* ```
* @param {String} code 授权获取到的code
*/
async getSessionKey(code) {
var info = {
appid: this.appid,
secret: this.appsecret,
js_code: code,
grant_type: 'authorization_code',
};

var url = `https://api.weixin.qq.com/sns/jscode2session?${querystring.stringify(info)}`;
var data = await this.request(url, {
headers: {
accept: 'application/json'
}
});

return this.processToken(data);
}

/**
* 根据refresh token,刷新access token,调用getAccessToken后才有效
* Examples:
Expand Down Expand Up @@ -262,6 +308,39 @@ class OAuth {
});
}

/**
* 根据服务器保存的sessionKey对从小程序客户端获取的加密用户数据进行解密
* Examples:
* ```
* api.decryptMiniProgramUser({encryptedData, iv});
* ```
* 返回值:
* ```
*{
* "openId": "OPENID",
* "nickName": "NICKNAME",
* "gender": "GENDER",
* "city": "CITY",
* "province": "PROVINCE",
* "country": "COUNTRY",
* "avatarUrl": "AVATARURL",
* "unionId": "UNIONID",
* "watermark":
* {
* "appid":"APPID",
* "timestamp":TIMESTAMP
* }
*}
* ```
* @param {Object} options 需要解密的对象
* @param {String} options.encryptedData 从小程序中获得的加密过的字符串
* @param {String} options.iv 从小程序中获得的加密算法初始向量
*/
decryptMiniProgramUser(options) {
var decrypter = new WxBizDataCrypt(this.appid, options.sessionKey);
return decrypter.decryptData(options.encryptedData, options.iv);
}

/**
* 根据openid,获取用户信息。
* 当access token无效时,自动通过refresh token获取新的access token。然后再获取用户信息
Expand Down Expand Up @@ -368,11 +447,30 @@ class OAuth {
* ]
* }
* ```
* @param {String} code 授权获取到的code
* @param {Object|String} options 授权获取到的code
*/
async getUserByCode(code) {
var token = await this.getAccessToken(code);
return this.getUser(token.data.openid);
async getUserByCode(options) {
var lang, code;
if (typeof options === 'string') {
code = options;
} else {
lang = options.lang;
code = options.code;
}

if (this.isMiniProgram) {
var result = await this.getSessionKey(code);
var sessionKey = result.data.session_key;
return this.decryptMiniProgramUser({
sessionKey,
encryptedData: options.encryptedData,
iv: options.iv,
});
} else {
var result = this.getAccessToken(code);
var openid = result.data.openid;
return this.getUser({openid: openid, lang: lang});
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"wechat"
],
"dependencies": {
"httpx": "^2.1.1"
"httpx": "^2.1.1",
"wechat-oauth": "^1.5.0"
},
"devDependencies": {
"coveralls": "*",
Expand Down