@gdjiami/jslib
Version:
Jiami FrontEnd helpers and Services
403 lines (322 loc) • 10.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
/**
* 通用的Token鉴权机制服务
*/
import { getSearch } from './http';
import { EventEmitter } from './EventEmitter';
export var SMS_CLIENT_TYPE = ['qxSMS', 'qxEEMS', 'qxEMS', 'qxCMS'];
export var TOKEN_HEADER = 'X-Access-Token';
/**
* 鉴权类型
*/
export var GRANT_TYPE;
(function (GRANT_TYPE) {
GRANT_TYPE["Auth"] = "authorization_code";
GRANT_TYPE["Refresh"] = "refresh_token";
})(GRANT_TYPE || (GRANT_TYPE = {}));
var TOKEN_CACHE_KEY = '__auth__';
var REFRESH_DURATION = 10 * 1000;
/**
* 基于Token的鉴权服务
* ## events
* info-updated
*/
export var TokenAuthService =
/*#__PURE__*/
function (_EventEmitter) {
_inheritsLoose(TokenAuthService, _EventEmitter);
function TokenAuthService(config) {
var _this;
_this = _EventEmitter.call(this) || this;
_this.refreshCallbacks = [];
_this.config = config;
_this.getUserInfo();
return _this;
}
var _proto = TokenAuthService.prototype;
_proto.logout = function logout() {
this.clean();
};
_proto.clean = function clean() {
// @ts-ignore
this.info = undefined;
this.storage.removeItem(TOKEN_CACHE_KEY);
}
/**
* 更新鉴权信息
*/
;
_proto.saveAuthInfo = function saveAuthInfo(info) {
this.info = info;
this.storage.setItem(TOKEN_CACHE_KEY, JSON.stringify(info));
this.infoUpdated();
}
/**
* 通过用户名密码鉴权
*/
;
_proto.authByPassword = function authByPassword(params) {
var info, res;
return _regeneratorRuntime.async(function authByPassword$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(this.config.getTokenByPassword == null)) {
_context.next = 2;
break;
}
throw new Error('TokenAuthService: getTokenByPassword 未实现');
case 2:
info = this.storage.getItem(TOKEN_CACHE_KEY);
if (!(info != null)) {
_context.next = 7;
break;
}
this.info = JSON.parse(info);
if (this.config.onAuthSuccess) {
this.config.onAuthSuccess(this.info);
}
return _context.abrupt("return");
case 7:
_context.prev = 7;
_context.next = 10;
return _regeneratorRuntime.awrap(this.config.getTokenByPassword(params));
case 10:
res = _context.sent;
this.saveAuthInfo(res);
this.handleAuthSuccess();
_context.next = 19;
break;
case 15:
_context.prev = 15;
_context.t0 = _context["catch"](7);
if (this.config.onAuthFailed) {
this.config.onAuthFailed(_context.t0);
}
throw _context.t0;
case 19:
case "end":
return _context.stop();
}
}
}, null, this, [[7, 15]]);
}
/**
* token 鉴权
*/
;
_proto.auth = function auth(overrideParams) {
var info, params, payload, res;
return _regeneratorRuntime.async(function auth$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (!(this.config.getToken == null)) {
_context2.next = 2;
break;
}
throw new Error('TokenAuthService: getToken 未实现');
case 2:
info = this.storage.getItem(TOKEN_CACHE_KEY);
if (!(info != null)) {
_context2.next = 7;
break;
}
this.info = JSON.parse(info);
if (this.config.onAuthSuccess) {
this.config.onAuthSuccess(this.info);
}
return _context2.abrupt("return");
case 7:
_context2.prev = 7;
params = getSearch(window.location.search);
if (!('from' in params)) {
_context2.next = 15;
break;
}
if (!(params.accessToken == null)) {
_context2.next = 12;
break;
}
throw new Error("\u9274\u6743\u5931\u8D25(from=" + params.from + ")\uFF0CaccessToken\u4E3Anull");
case 12:
this.saveAuthInfo(params);
this.handleAuthSuccess();
return _context2.abrupt("return");
case 15:
if (!(params.code == null)) {
_context2.next = 17;
break;
}
throw new Error('鉴权失败,code为null');
case 17:
payload = _extends({
code: params.code,
corpId: params.corp_id || '',
clientId: this.config.clientId,
grantType: GRANT_TYPE.Auth
}, overrideParams || {});
_context2.next = 20;
return _regeneratorRuntime.awrap(this.config.getToken(payload));
case 20:
res = _context2.sent;
this.saveAuthInfo(res);
this.handleAuthSuccess();
_context2.next = 29;
break;
case 25:
_context2.prev = 25;
_context2.t0 = _context2["catch"](7);
if (this.config.onAuthFailed) {
this.config.onAuthFailed(_context2.t0);
}
throw _context2.t0;
case 29:
case "end":
return _context2.stop();
}
}
}, null, this, [[7, 25]]);
}
/**
* 刷新token
* 这个方法可能会被调用多次,所以要将它们加入队列,以便后续重试
*/
;
_proto.refresh = function refresh() {
var resRef, rejRef, promise, params, res, now, list, _list;
return _regeneratorRuntime.async(function refresh$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
if (!(this.info == null)) {
_context3.next = 2;
break;
}
throw new Error('必须在鉴权之后才能刷新Token');
case 2:
if (!this.refreshing) {
_context3.next = 8;
break;
}
promise = new Promise(function (res, rej) {
resRef = res;
rejRef = rej;
});
this.refreshCallbacks.push(function (err) {
return err != null ? rejRef(err) : resRef();
});
_context3.next = 7;
return _regeneratorRuntime.awrap(promise);
case 7:
return _context3.abrupt("return");
case 8:
_context3.prev = 8;
params = {
refreshToken: this.info.refreshToken,
grantType: GRANT_TYPE.Refresh
};
_context3.next = 12;
return _regeneratorRuntime.awrap(this.config.refreshToken(params));
case 12:
res = _context3.sent;
now = Date.now();
if (!(this.lastRefreshTime != null && now - this.lastRefreshTime < REFRESH_DURATION)) {
_context3.next = 16;
break;
}
throw new Error(this.config.refreshErrorMessage || '会话失效');
case 16:
this.lastRefreshTime = now;
this.saveAuthInfo(_extends({}, this.info, {}, res));
if (this.refreshCallbacks.length) {
list = this.refreshCallbacks;
this.refreshCallbacks = [];
list.forEach(function (i) {
return i();
});
}
_context3.next = 27;
break;
case 21:
_context3.prev = 21;
_context3.t0 = _context3["catch"](8);
if (this.refreshCallbacks.length) {
_list = this.refreshCallbacks;
this.refreshCallbacks = [];
_list.forEach(function (i) {
return i(_context3.t0);
});
}
if (this.config.onRefreshFailed) {
this.config.onRefreshFailed(_context3.t0);
} // 清理鉴权信息
this.clean();
throw _context3.t0;
case 27:
_context3.prev = 27;
this.refreshing = false;
return _context3.finish(27);
case 30:
case "end":
return _context3.stop();
}
}
}, null, this, [[8, 21, 27, 30]]);
};
_proto.isAdmin = function isAdmin() {
return SMS_CLIENT_TYPE.indexOf(this.info.clientType) !== -1;
}
/**
* 获取token
*/
;
_proto.getToken = function getToken() {
return this.info && this.info.accessToken;
}
/**
* 获取用户信息
*/
;
_proto.getUserInfo = function getUserInfo() {
if (this.info) {
return this.info;
}
var info = this.storage.getItem(TOKEN_CACHE_KEY);
if (info != null) {
this.info = JSON.parse(info);
}
return this.info;
};
_proto.infoUpdated = function infoUpdated() {
var _this2 = this;
this.emit(TokenAuthService.INFO_UPDATED, this.info);
var deadline = this.info.deadline;
if (deadline == null || this.config.refreshToken == null) {
return;
}
var delta = deadline - Date.now();
if (delta > 0) {
window.clearTimeout(this.refreshTimer);
this.refreshTimer = window.setTimeout(function () {
_this2.refresh();
}, Math.floor(delta * 0.7));
}
};
_proto.handleAuthSuccess = function handleAuthSuccess() {
if (this.config.onAuthSuccess) {
this.config.onAuthSuccess(this.info);
}
};
_createClass(TokenAuthService, [{
key: "storage",
get: function get() {
return this.config && this.config.storage || window.sessionStorage;
}
}]);
return TokenAuthService;
}(EventEmitter);
TokenAuthService.INFO_UPDATED = 'info-updated';