koa3-wechat
Version:
wechat api modified by windsome.feng
335 lines (292 loc) • 10.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _debug2 = require('debug');
var _debug3 = _interopRequireDefault(_debug2);
var _base = require('./base');
var _base2 = _interopRequireDefault(_base);
var _querystring = require('querystring');
var _querystring2 = _interopRequireDefault(_querystring);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var debug = (0, _debug3.default)('app:wechat:oauth');
var Oauth = function (_Base) {
(0, _inherits3.default)(Oauth, _Base);
function Oauth() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck3.default)(this, Oauth);
return (0, _possibleConstructorReturn3.default)(this, (Oauth.__proto__ || (0, _getPrototypeOf2.default)(Oauth)).call(this, opts));
}
/**
* 获取授权页面的URL地址
* @param {String} redirect 授权后要跳转的地址
* @param {String} state 开发者可提供的数据
* @param {String} scope 作用范围,值为snsapi_userinfo和snsapi_base,前者用于弹出,后者用于跳转
*/
(0, _createClass3.default)(Oauth, [{
key: 'getAuthorizeURL',
value: function getAuthorizeURL(redirect, state, scope) {
var url = 'https://open.weixin.qq.com/connect/oauth2/authorize';
var info = {
appid: this.getAppId(),
redirect_uri: redirect,
response_type: 'code',
scope: scope || 'snsapi_base',
state: state || ''
};
return url + '?' + _querystring2.default.stringify(info) + '#wechat_redirect';
}
/**
* 获取授权页面的URL地址
* @param {String} redirect 授权后要跳转的地址
* @param {String} state 开发者可提供的数据
* @param {String} scope 作用范围,值为snsapi_login,前者用于弹出,后者用于跳转
*/
}, {
key: 'getAuthorizeURLForWebsite',
value: function getAuthorizeURLForWebsite(redirect, state, scope) {
var url = 'https://open.weixin.qq.com/connect/qrconnect';
var info = {
appid: this.getAppId(),
redirect_uri: redirect,
response_type: 'code',
scope: scope || 'snsapi_login',
state: state || ''
};
return url + '?' + _querystring2.default.stringify(info) + '#wechat_redirect';
}
/**
* 根据授权获取到的code,换取access token和openid
* 获取openid之后,可以调用`wechat.API`来获取更多信息
* Examples:
* ```
* api.getOauthAccessToken(code, callback);
* ```
* Callback:
*
* - `err`, 获取access token出现异常时的异常对象
* - `result`, 成功时得到的响应结果
*
* Result:
* ```
* {
* data: {
* "access_token": "ACCESS_TOKEN",
* "expires_in": 7200,
* "refresh_token": "REFRESH_TOKEN",
* "openid": "OPENID",
* "scope": "SCOPE"
* }
* }
* ```
* @param {String} code 授权获取到的code
* @param {Function} callback 回调函数
*/
}, {
key: 'getOauthAccessToken',
value: function getOauthAccessToken(code) {
var url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code'.replace(/APPID/g, this.getAppId()).replace(/SECRET/g, this.getAppSecret()).replace(/CODE/g, code);
return this.get(url).then(function (retobj) {
if (!(retobj && retobj.openid)) {
debug('warning! not get openid!', retobj);
}
// // TODO: do we need save tokens?
// return this.backend.mset('oauthAccessTokens', retobj.openid, retobj);
return retobj;
});
}
/**
* 根据refresh token,刷新access token,调用getAccessToken后才有效
* Examples:
* ```
* api.refreshAccessToken(refreshToken, callback);
* ```
* Callback:
*
* - `err`, 刷新access token出现异常时的异常对象
* - `result`, 成功时得到的响应结果
*
* Result:
* ```
* {
* data: {
* "access_token": "ACCESS_TOKEN",
* "expires_in": 7200,
* "refresh_token": "REFRESH_TOKEN",
* "openid": "OPENID",
* "scope": "SCOPE"
* }
* }
* ```
* @param {String} refreshToken refreshToken
* @param {Function} callback 回调函数
*/
}, {
key: 'refreshOauthAccessToken',
value: function refreshOauthAccessToken(refreshToken) {
var url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN'.replace(/APPID/g, this.getAppId()).replace(/REFRESH_TOKEN/g, refreshToken);
return this.get(url).then(function (retobj) {
if (!(retobj && retobj.openid)) {
debug('warning! not get openid!', retobj);
}
// // TODO: do we need save tokens?
// return this.backend.mset('oauthAccessTokens', retobj.openid, retobj);
return retobj;
});
}
}, {
key: '_getUser',
value: function _getUser(openid, oauthAccessToken) {
var url = 'https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN'.replace(/ACCESS_TOKEN/g, oauthAccessToken).replace(/OPENID/g, openid);
return this.get(url).then(function (retobj) {
if (!(retobj && retobj.openid)) {
debug('warning! not get userinfo!', retobj);
}
return retobj;
});
}
/**
* 根据openid,获取用户信息。
* 当access token无效时,自动通过refresh token获取新的access token。然后再获取用户信息
* Examples:
* ```
* api.getUser(options, callback);
* ```
*
* Options:
* ```
* openId
* // 或
* {
* "openid": "the open Id", // 必须
* "lang": "the lang code" // zh_CN 简体,zh_TW 繁体,en 英语
* }
* ```
* Result:
* ```
* {
* "openid": "OPENID",
* "nickname": "NICKNAME",
* "sex": "1",
* "province": "PROVINCE"
* "city": "CITY",
* "country": "COUNTRY",
* "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
* "privilege": [
* "PRIVILEGE1"
* "PRIVILEGE2"
* ]
* }
* ```
* @param {Object|String} options 传入openid或者参见Options
* @param {Function} callback 回调函数
*/
}, {
key: 'getUser',
value: function getUser(oauthAccessToken) {
var _this2 = this;
return this._getUser(oauthAccessToken.openid, oauthAccessToken.access_token).then(function (retobj) {
if (retobj.openid) {
debug('get user info success!');
return retobj;
} else {
debug('get user info fail! try refresh token', retobj);
return _this2.refreshOauthAccessToken(oauthAccessToken.refresh_token).then(function (retobj2) {
if (retobj2 && retobj2.openid) {
debug('refresh oauth token ok! try get user info again');
return _this2._getUser(retobj2.openid, retobj2.access_token);
} else {
// return old _getUser() error.
return retobj;
}
});
}
});
}
/**
* 检验授权凭证(access_token)是否有效。
* Examples:
* ```
* api.verifyToken(openid, accessToken, callback);
* ```
* @param {String} openid 传入openid
* @param {String} accessToken 待校验的access token
* @param {Function} callback 回调函数
*/
}, {
key: 'verifyOauthToken',
value: function verifyOauthToken(openid, oauthAccessToken) {
var url = 'https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID'.replace(/ACCESS_TOKEN/g, oauthAccessToken).replace(/OPENID/g, openid);
return this.get(url).then(function (retobj) {
if (retobj && retobj.errcode === 0) {
//return true;
} else {
debug('verify fail!', retobj);
}
return retobj;
});
}
/**
* 根据code,获取用户信息。
* Examples:
* ```
* api.getUserByCode(code, callback);
* ```
* Callback:
*
* - `err`, 获取用户信息出现异常时的异常对象
* - `result`, 成功时得到的响应结果
*
* Result:
* ```
* {
* "openid": "OPENID",
* "nickname": "NICKNAME",
* "sex": "1",
* "province": "PROVINCE"
* "city": "CITY",
* "country": "COUNTRY",
* "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
* "privilege": [
* "PRIVILEGE1"
* "PRIVILEGE2"
* ]
* }
* ```
* @param {Object|String} options 授权获取到的code
* @param {Function} callback 回调函数
*/
}, {
key: 'getUserByCode',
value: function getUserByCode(code /*, scope1*/) {
var _this3 = this;
return this.getOauthAccessToken(code).then(function (retobj) {
if (!retobj) return retobj;
if (!retobj.openid) {
debug('warning! not get openid!', retobj);
}
if (retobj.scope === 'snsapi_userinfo') {
return _this3.getUser(retobj).then(function (retobj2) {
if (!retobj2) return retobj2;else return (0, _extends3.default)({}, retobj2, { scope: retobj.scope });
});
} else {
return (0, _extends3.default)({}, retobj, { scope: retobj.scope });
}
});
}
}]);
return Oauth;
}(_base2.default);
exports.default = Oauth;