fcs
2025-04-10 0163870d662dc5b7d69ceff977490ede594f7d82
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
'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;