'use strict';
|
/**
|
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
*
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
* the License. You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
* specific language governing permissions and limitations under the License.
|
*
|
* @file baseClient
|
* @author baiduAip
|
*/
|
const DevAuth = require('../auth/devAuth');
|
|
const DevAuthToken = require('../auth/devAuthToken');
|
|
|
/**
|
* 无授权判断状态
|
*
|
* @const
|
* @type {number}
|
*/
|
const AUTHTYPE_INIT = 0;
|
|
/**
|
* 确定为云用户
|
*
|
* @const
|
* @type {number}
|
*/
|
const AUTHTYPE_BCE = 1;
|
|
/**
|
* 确定为开发者用户(手动输入token模式,以及token中包含了正确的scope)
|
*
|
* @const
|
* @type {number}
|
*/
|
const AUTHTYPE_DEV = 2;
|
|
/**
|
* 获取开发者token成功用户
|
*
|
* @const
|
* @type {number}
|
*/
|
const AUTHTYPE_DEV_OR_BCE = 3;
|
|
|
/**
|
* 初始状态
|
*
|
* @const
|
* @type {number}
|
*/
|
const STATUS_INIT = 0;
|
|
/**
|
* 获取开发者token中
|
*
|
* @const
|
* @type {number}
|
*/
|
const STATUS_AUTHTYPE_REQESTING = 1;
|
|
/**
|
* 获取开发者token成功,或者确定为云用户
|
*
|
* @const
|
* @type {number}
|
*/
|
const STATUS_READY = 2;
|
|
/**
|
* 非法ak,sk
|
*
|
* @const
|
* @type {number}
|
*/
|
const STATUS_ERROR = -1;
|
|
/**
|
* BaseClient类
|
* 各具体接口类基类,处理鉴权逻辑等
|
*
|
* @constructor
|
* @param {string} appid appid.
|
* @param {string} ak The access key.
|
* @param {string} sk The security key.
|
*/
|
class BaseClient {
|
constructor(appId, ak, sk) {
|
this.appId = 0;
|
this.ak = ak;
|
this.sk = sk;
|
|
this.authType = AUTHTYPE_INIT;
|
this.status = STATUS_INIT;
|
|
this.pms;
|
|
this.devAccessToken = null;
|
|
this.devAuth = new DevAuth(this.ak, this.sk);
|
|
this.authTypeReq();
|
}
|
setAccessToken(token, expireTime) {
|
let et = expireTime || DevAuthToken.DEFAULT_EXPIRE_DURATION;
|
this.devAccessToken = new DevAuthToken(token, et, null);
|
this.authType = AUTHTYPE_DEV;
|
this.status = STATUS_READY;
|
}
|
authTypeReq() {
|
// 请求access_token服务
|
this.status = STATUS_AUTHTYPE_REQESTING;
|
|
return this.pms = this.devAuth.getToken().then(this.gotDevAuthSuccess.bind(this),
|
this.gotDevAuthFail.bind(this));
|
}
|
gotDevAuthSuccess(token) {
|
// 如果用户没有手动调用setAccessToken设置access_token
|
if (this.authType !== AUTHTYPE_DEV) {
|
this.devAccessToken = token;
|
this.authType = AUTHTYPE_DEV_OR_BCE;
|
}
|
this.status = STATUS_READY;
|
return;
|
}
|
gotDevAuthFail(err) {
|
// 获取token时鉴权服务器返回失败信息
|
if (err.errorType === DevAuth.EVENT_ERRTYPE_NORMAL) {
|
// 可能是百度云的ak,sk
|
this.authType = AUTHTYPE_BCE;
|
this.status = STATUS_READY;
|
return;
|
}
|
|
// 获取token时发生了网络错误
|
// 或者是发生了服务器返回数据格式异常
|
if (err.errorType === DevAuth.EVENT_ERRTYPE_NETWORK
|
|| err.errorType === DevAuth.EVENT_ERRTYPE_ILLEGAL_RESPONSE) {
|
this.status = STATUS_ERROR;
|
throw err;
|
}
|
}
|
doRequest(requestInfo, httpClient) {
|
return this.pms.then(function() {
|
let pms = this.preRequest(requestInfo);
|
|
if (typeof pms == "undefined") {
|
// 鉴权方式确定,请求接口
|
return httpClient.postWithInfo(requestInfo)
|
} else {
|
// 如果返回对象是promise,说明是需要重新获取access_token
|
// 待重新获取完后继续请求接口
|
return pms.then(function() {
|
this.preRequest(requestInfo);
|
return httpClient.postWithInfo(requestInfo);
|
}.bind(this))
|
}
|
}.bind(this))
|
}
|
preRequest(requestInfo) {
|
// 如果前一次获取access_token服务发生错误,重新获取
|
if (this.status == STATUS_ERROR) {
|
return this.authTypeReq();
|
}
|
|
// 获取access_token失败,使用云方式调用
|
if (this.authType === AUTHTYPE_BCE) {
|
requestInfo.makeBceOptions(this.ak, this.sk);
|
return;
|
}
|
|
// 获取access_token成功,或者调用setAccessToken设置的access_token
|
if (this.authType === AUTHTYPE_DEV_OR_BCE || this.authType === AUTHTYPE_DEV) {
|
// 拥有AI平台接口权限
|
if (this.devAccessToken.hasScope(requestInfo.scope) || this.authType === AUTHTYPE_DEV) {
|
// 判断access_token是否过期
|
if (!this.devAccessToken.isExpired()) {
|
requestInfo.makeDevOptions(this.devAccessToken);
|
return;
|
}
|
// access_token过期重新获取
|
return this.authTypeReq();
|
} else {
|
// 使用云方式访问调用
|
requestInfo.makeBceOptions(this.ak, this.sk);
|
}
|
}
|
}
|
}
|
|
module.exports = BaseClient;
|