使用不记名令牌的 IBM Cloud Speech-to-Text SDK 身份验证失败
IBM Cloud Speech-to-Text SDK auth failures with bearer token
我正在学习使用 Watson Speech JS SDK. In particular I like Transcribe from Microphone, with Alternatives。我正在使用 Firebase 云函数生成我的令牌。我使用的是 AngularJS,而不是 JQuery。我 运行 遇到的第一个问题是
var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(Object.assign(token, {
objectMode: true,
format: false,
wordConfidence: true
}));
我收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token
(使用 $scope.token
或 token
没有区别。)
在 documentation 中查找此错误:
module.exports = function recognizeMicrophone(options) {
if (!options || !options.token) {
throw new Error('WatsonSpeechToText: missing required parameter: opts.token');
}
好的,它正在寻找一个 options
对象。我用这段代码修复了错误:
const options = {
token: $scope.token,
objectMode: true,
format: false,
wordConfidence: true
};
console.log(options);
var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(options);
现在我得到这个错误:
WebSocket connection to 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?model=en-US_BroadbandModel&watson-token=[object%20Object]' failed: HTTP Authentication failed; no valid credentials available
options
对象记录如下:
token:
access_token: "eyJraWQiOiIyMDIwMDIyNTE4MjgiLCJhbGciOiJSUzI1NiJ9.eyJpYW1faWQiOiJp0tU2..."
expiration: 1585332575
expires_in: 3600
refresh_token: "OKC8z8ebLMzZcrAt6YgInnJJn0UIx1P3NTeDvdEC3kJqIQ7Yn9J9iu6-DF..."
scope: "ibm openid"
token_type: "Bearer"
objectMode: true
format: false
wordConfidence: true
smart_formatting: false
令牌是一个 JSON 对象,其中包括 access_token
。这是SDK想要的吗? RecognizeStream documentation 没有说明它是想要 JSON 令牌还是只需要裸 access_token
.
将 000
添加到 expiration
字段表明我在该令牌上还剩 53 分钟。
我正在使用特定于我的 Speech-to-Text 服务的 API 键。
还有其他建议吗?
SDK 版本 0.37.0 引入了重大更改:
All options parameters for all methods are coverted to be lowerCamelCase
For example: access_token is now accessToken and content-type is now contentType
这与 IBM 从具有 username/password 身份验证的 Cloud Foundry 服务迁移到具有 IAM 身份验证和 api 密钥的服务有关。 SDK documentation 表示:
NOTE: The token parameter only works for CF instances of services. For RC services using IAM for authentication, the accessToken parameter must be used.
如果您使用 api 键,options
对象看起来像这样:
const options = {
accessToken: $scope.token,
objectMode: true,
format: false,
wordConfidence: true
};
如果您遗漏了令牌 属性,您会收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token (CF) or opts.accessToken (RC)
这意味着,如果您从 Cloud Foundry (CF) 获取令牌,则 属性 必须是 opts.token
(或 options.token
);但是如果你从 IAM auth 和一个 api-key 得到你的令牌,我不知道为什么它被称为 RC
,那么 属性 必须是 opts.accessToken
(或 options.accessToken
)。
令人困惑的是,demo source code 暗示 access_token
是 属性 名称:
var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(Object.assign(token, {
objectMode: true,
format: false,
wordConfidence: true
}));
Object.assign
使用来自 IBM 的 target
令牌对象,然后添加或替换 source
对象中的属性和值。因为 IAM 令牌中的 属性 是 access_token
,您会认为,因为演示运行,access_token
是 属性。但显然该演示是 Cloud Foundry 令牌上的 运行,它可以使用 token
或 access_token
作为 属性 名称。
如果您收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token (CF) or opts.accessToken (RC)
那么您既没有使用 token
也没有使用 accessToken
作为 属性 名称。
如果您收到此错误消息:
WebSocket connection to 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?model=en-US_BroadbandModel&watson-token=[object%20Object]' failed: HTTP Authentication failed; no valid credentials available
那么您正在使用 token
以及使用 IAM api 密钥生成的令牌。或者您的令牌已过期。您可以通过将此代码放入您的应用程序来轻松检查,以告诉您令牌还剩多少分钟:
// shows time to token expiration
var expiry = new Date($scope.token.expiration * 1000);
var now = Date.now();
var duration = -(now - expiry);
function msToTime(duration) {
var milliseconds = parseInt((duration % 1000) / 100),
seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return "Token expires in " + minutes + ":" + seconds + " minutes:seconds";
}
console.log(msToTime(duration))
您可以从 CLI 测试您的令牌是否有效。首先获得一个新令牌:
curl -k -X POST \
--header "Content-Type: application/x-www-form-urlencoded" \
--header "Accept: application/json" \
--data-urlencode "grant_type=urn:ibm:params:oauth:grant-type:apikey" \
--data-urlencode "apikey=s00pers3cret" \
"https://iam.cloud.ibm.com/identity/token"
然后请求语言模型:
curl -X GET "https://stream.watsonplatform.net/speech-to-text/api/v1/models?access_token=eyJraWQiO...."
我的代码中还有另一个问题。我正在更新 IBM Speech-to-Text SDK,但我的代码链接到我三年前用 Bower 安装的旧 SDK。当 0.38.0 是最新版本时,我没有意识到我正在使用 0.33.1。将此添加到您的代码中以解决此问题:
console.log (WatsonSpeech.version);
使用旧的 SDK 我收到一条旧的错误消息,甚至没有提到新的 属性 名称:
WatsonSpeechToText: missing required parameter: opts.token
我的 blog post 有更多关于 IBM Cloud Speech-to-Text 的信息。
我正在学习使用 Watson Speech JS SDK. In particular I like Transcribe from Microphone, with Alternatives。我正在使用 Firebase 云函数生成我的令牌。我使用的是 AngularJS,而不是 JQuery。我 运行 遇到的第一个问题是
var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(Object.assign(token, {
objectMode: true,
format: false,
wordConfidence: true
}));
我收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token
(使用 $scope.token
或 token
没有区别。)
在 documentation 中查找此错误:
module.exports = function recognizeMicrophone(options) {
if (!options || !options.token) {
throw new Error('WatsonSpeechToText: missing required parameter: opts.token');
}
好的,它正在寻找一个 options
对象。我用这段代码修复了错误:
const options = {
token: $scope.token,
objectMode: true,
format: false,
wordConfidence: true
};
console.log(options);
var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(options);
现在我得到这个错误:
WebSocket connection to 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?model=en-US_BroadbandModel&watson-token=[object%20Object]' failed: HTTP Authentication failed; no valid credentials available
options
对象记录如下:
token:
access_token: "eyJraWQiOiIyMDIwMDIyNTE4MjgiLCJhbGciOiJSUzI1NiJ9.eyJpYW1faWQiOiJp0tU2..."
expiration: 1585332575
expires_in: 3600
refresh_token: "OKC8z8ebLMzZcrAt6YgInnJJn0UIx1P3NTeDvdEC3kJqIQ7Yn9J9iu6-DF..."
scope: "ibm openid"
token_type: "Bearer"
objectMode: true
format: false
wordConfidence: true
smart_formatting: false
令牌是一个 JSON 对象,其中包括 access_token
。这是SDK想要的吗? RecognizeStream documentation 没有说明它是想要 JSON 令牌还是只需要裸 access_token
.
将 000
添加到 expiration
字段表明我在该令牌上还剩 53 分钟。
我正在使用特定于我的 Speech-to-Text 服务的 API 键。
还有其他建议吗?
SDK 版本 0.37.0 引入了重大更改:
All options parameters for all methods are coverted to be lowerCamelCase
For example: access_token is now accessToken and content-type is now contentType
这与 IBM 从具有 username/password 身份验证的 Cloud Foundry 服务迁移到具有 IAM 身份验证和 api 密钥的服务有关。 SDK documentation 表示:
NOTE: The token parameter only works for CF instances of services. For RC services using IAM for authentication, the accessToken parameter must be used.
如果您使用 api 键,options
对象看起来像这样:
const options = {
accessToken: $scope.token,
objectMode: true,
format: false,
wordConfidence: true
};
如果您遗漏了令牌 属性,您会收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token (CF) or opts.accessToken (RC)
这意味着,如果您从 Cloud Foundry (CF) 获取令牌,则 属性 必须是 opts.token
(或 options.token
);但是如果你从 IAM auth 和一个 api-key 得到你的令牌,我不知道为什么它被称为 RC
,那么 属性 必须是 opts.accessToken
(或 options.accessToken
)。
令人困惑的是,demo source code 暗示 access_token
是 属性 名称:
var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(Object.assign(token, {
objectMode: true,
format: false,
wordConfidence: true
}));
Object.assign
使用来自 IBM 的 target
令牌对象,然后添加或替换 source
对象中的属性和值。因为 IAM 令牌中的 属性 是 access_token
,您会认为,因为演示运行,access_token
是 属性。但显然该演示是 Cloud Foundry 令牌上的 运行,它可以使用 token
或 access_token
作为 属性 名称。
如果您收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token (CF) or opts.accessToken (RC)
那么您既没有使用 token
也没有使用 accessToken
作为 属性 名称。
如果您收到此错误消息:
WebSocket connection to 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?model=en-US_BroadbandModel&watson-token=[object%20Object]' failed: HTTP Authentication failed; no valid credentials available
那么您正在使用 token
以及使用 IAM api 密钥生成的令牌。或者您的令牌已过期。您可以通过将此代码放入您的应用程序来轻松检查,以告诉您令牌还剩多少分钟:
// shows time to token expiration
var expiry = new Date($scope.token.expiration * 1000);
var now = Date.now();
var duration = -(now - expiry);
function msToTime(duration) {
var milliseconds = parseInt((duration % 1000) / 100),
seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return "Token expires in " + minutes + ":" + seconds + " minutes:seconds";
}
console.log(msToTime(duration))
您可以从 CLI 测试您的令牌是否有效。首先获得一个新令牌:
curl -k -X POST \
--header "Content-Type: application/x-www-form-urlencoded" \
--header "Accept: application/json" \
--data-urlencode "grant_type=urn:ibm:params:oauth:grant-type:apikey" \
--data-urlencode "apikey=s00pers3cret" \
"https://iam.cloud.ibm.com/identity/token"
然后请求语言模型:
curl -X GET "https://stream.watsonplatform.net/speech-to-text/api/v1/models?access_token=eyJraWQiO...."
我的代码中还有另一个问题。我正在更新 IBM Speech-to-Text SDK,但我的代码链接到我三年前用 Bower 安装的旧 SDK。当 0.38.0 是最新版本时,我没有意识到我正在使用 0.33.1。将此添加到您的代码中以解决此问题:
console.log (WatsonSpeech.version);
使用旧的 SDK 我收到一条旧的错误消息,甚至没有提到新的 属性 名称:
WatsonSpeechToText: missing required parameter: opts.token
我的 blog post 有更多关于 IBM Cloud Speech-to-Text 的信息。