hera-cli
Version:
Hera Project Creator
187 lines (164 loc) • 5.05 kB
JavaScript
var utils = require('./utils')
var constants = require('./constants')
var Session = require('./session')
/***
* @class
* 表示登录过程中发生的异常
*/
var LoginError = (function () {
function LoginError (type, message) {
Error.call(this, message)
this.type = type
this.message = message
}
LoginError.prototype = new Error()
LoginError.prototype.constructor = LoginError
return LoginError
})()
/**
* 微信登录,获取 code 和 encryptData
*/
var getWxLoginResult = function getLoginCode (callback) {
wx.login({
success: function (loginResult) {
wx.getUserInfo({
success: function (userResult) {
callback(null, {
code: loginResult.code,
encryptedData: userResult.encryptedData,
iv: userResult.iv,
userInfo: userResult.userInfo
})
},
fail: function (userError) {
var error = new LoginError(
constants.ERR_WX_GET_USER_INFO,
'获取微信用户信息失败,请检查网络状态'
)
error.detail = userError
callback(error, null)
}
})
},
fail: function (loginError) {
var error = new LoginError(
constants.ERR_WX_LOGIN_FAILED,
'微信登录失败,请检查网络状态'
)
error.detail = loginError
callback(error, null)
}
})
}
var noop = function noop () {}
var defaultOptions = {
method: 'GET',
success: noop,
fail: noop,
loginUrl: null
}
/**
* @method
* 进行服务器登录,以获得登录会话
*
* @param {Object} options 登录配置
* @param {string} options.loginUrl 登录使用的 URL,服务器应该在这个 URL 上处理登录请求
* @param {string} [options.method] 请求使用的 HTTP 方法,默认为 "GET"
* @param {Function} options.success(userInfo) 登录成功后的回调函数,参数 userInfo 微信用户信息
* @param {Function} options.fail(error) 登录失败后的回调函数,参数 error 错误信息
*/
var login = function login (options) {
options = utils.extend({}, defaultOptions, options)
if (!defaultOptions.loginUrl) {
options.fail(
new LoginError(
constants.ERR_INVALID_PARAMS,
'登录错误:缺少登录地址,请通过 setLoginUrl() 方法设置登录地址'
)
)
return
}
var doLogin = () =>
getWxLoginResult(function (wxLoginError, wxLoginResult) {
if (wxLoginError) {
options.fail(wxLoginError)
return
}
var userInfo = wxLoginResult.userInfo
// 构造请求头,包含 code、encryptedData 和 iv
var code = wxLoginResult.code
var encryptedData = wxLoginResult.encryptedData
var iv = wxLoginResult.iv
var header = {}
header[constants.WX_HEADER_CODE] = code
header[constants.WX_HEADER_ENCRYPTED_DATA] = encryptedData
header[constants.WX_HEADER_IV] = iv
// 请求服务器登录地址,获得会话信息
wx.request({
url: options.loginUrl,
header: header,
method: options.method,
data: options.data,
success: function (result) {
var data = result.data
// 成功地响应会话信息
if (data && data[constants.WX_SESSION_MAGIC_ID]) {
if (data.session) {
data.session.userInfo = userInfo
Session.set(data.session)
options.success(userInfo)
} else {
var errorMessage =
'登录失败(' + data.error + '):' + (data.message || '未知错误')
var noSessionError = new LoginError(
constants.ERR_LOGIN_SESSION_NOT_RECEIVED,
errorMessage
)
options.fail(noSessionError)
}
// 没有正确响应会话信息
} else {
var errorMessage =
'登录请求没有包含会话响应,请确保服务器处理 `' +
options.loginUrl +
'` 的时候正确使用了 SDK 输出登录结果'
var noSessionError = new LoginError(
constants.ERR_LOGIN_SESSION_NOT_RECEIVED,
errorMessage
)
options.fail(noSessionError)
}
},
// 响应错误
fail: function (loginResponseError) {
var error = new LoginError(
constants.ERR_LOGIN_FAILED,
'登录失败,可能是网络错误或者服务器发生异常'
)
options.fail(error)
}
})
})
var session = Session.get()
if (session) {
wx.checkSession({
success: function () {
options.success(session.userInfo)
},
fail: function () {
Session.clear()
doLogin()
}
})
} else {
doLogin()
}
}
var setLoginUrl = function (loginUrl) {
defaultOptions.loginUrl = loginUrl
}
module.exports = {
LoginError: LoginError,
login: login,
setLoginUrl: setLoginUrl
}