带有承载令牌的IBM Cloud语音到文本SDK身份验证失败 [英] IBM Cloud Speech-to-Text SDK auth failures with bearer token
问题描述
我正在学习使用 Watson Speech JS SDK .我特别喜欢从麦克风转录,并带有其他选择.我正在使用Firebase Cloud Function生成令牌.我正在使用AngularJS,而不是JQuery.我遇到的第一个问题是
I'm learning to use the Watson Speech JS SDK. In particular I like Transcribe from Microphone, with Alternatives. I'm generating my token with a Firebase Cloud Function. I'm using AngularJS, not JQuery. The first problem I'm running into is
var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(Object.assign(token, {
objectMode: true,
format: false,
wordConfidence: true
}));
我收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token
(使用$scope.token
或token
没有区别.)
在文档:
module.exports = function recognizeMicrophone(options) {
if (!options || !options.token) {
throw new Error('WatsonSpeechToText: missing required parameter: opts.token');
}
好,它正在寻找一个options
对象.我使用以下代码修复了错误:
OK, it's looking for an options
object. I fixed the error with this code:
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文档没有说明是否它需要JSON令牌,或者只需要裸露的access_token
.
The token is a JSON object, which includes the access_token
. Is this what the SDK wants? The RecognizeStream documentation doesn't say whether it wants the JSON token or just the naked access_token
.
在expiration
字段中添加000
表明该令牌还剩53分钟.
Adding 000
to the expiration
field shows that I have 53 minutes left on this token.
我正在使用特定于我的语音转文本服务的API密钥.
I'm using the API key that's specific to my Speech-to-Text service.
还有其他建议吗?
推荐答案
版本 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从具有用户名/密码身份验证的Cloud Foundry服务到具有IAM身份验证和api密钥的服务有关. SDK文档说:
This is related to IBM's move from Cloud Foundry services with username/password auth to Services with IAM auth and api keys. The SDK documentation says:
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
对象将如下所示:
The options
object looks like this if you use an api key:
const options = {
accessToken: $scope.token,
objectMode: true,
format: false,
wordConfidence: true
};
如果忽略令牌属性,则会收到以下错误消息:
If you leave out the token property you get this error message:
WatsonSpeechToText: missing required parameter: opts.token (CF) or opts.accessToken (RC)
这意味着,如果要从Cloud Foundry(CF)获取令牌,则该属性必须为opts.token
(或options.token
);但是,如果您从IAM身份验证和一个api-key(无缘无故被称为RC
)获取令牌,则该属性必须为opts.accessToken
(或options.accessToken
).
What that means is, if you're getting your token from Cloud Foundry (CF) the property must be opts.token
(or options.token
); but if you're getting your token from IAM auth and an api-key, which is called RC
for no reason I know of, then the property must be opts.accessToken
(or options.accessToken
).
令人困惑的是,演示源代码表示access_token
是属性名称:
Confusing the matter, the demo source code implies that access_token
is the property name:
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
作为属性名称.
Object.assign
is taking the target
token object as it comes from IBM and then adding or replacing the properties and values in the source
object. Because the property is access_token
in the IAM token you'd think that, because the demo runs, access_token
is the property. But apparently the demo is running on a Cloud Foundry token, which can use either token
or access_token
as the property name.
如果收到此错误消息:
WatsonSpeechToText: missing required parameter: opts.token (CF) or opts.accessToken (RC)
然后,您既不使用token
也不使用accessToken
作为属性名称.
then you're using neither token
nor accessToken
as the property name.
如果收到此错误消息:
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密钥生成的令牌一起使用.否则您的令牌已过期.您可以通过将以下代码放在您的应用中来告诉您令牌还剩多少分钟,从而轻松进行检查:
then you're using token
with a token generated with an IAM api-key. Or your token is expired. You can check that easily by putting this code in your app to tell you how many minutes are left on your token:
// 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测试令牌是否有效.首先获得一个新令牌:
You can test if your token is valid from the CLI. First get a new token:
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语音到文本SDK ,但是我的代码链接到三年前在Bower上安装的旧SDK.我没有意识到当0.38.0是最新版本时我正在使用0.33.1.将此添加到您的代码以解决此问题:
I had another problem in my code. I was updating the IBM Speech-to-Text SDK but my code was linking to an old SDK I'd installed with bower three years ago. I didn't realize that I was using 0.33.1 when 0.38.0 is the latest version. Add this to your code to catch this problem:
console.log (WatsonSpeech.version);
使用旧的SDK时,我收到一条旧的错误消息,甚至没有提到新的属性名称:
With the old SDK I was getting an old error message that didn't even mention the new property name:
WatsonSpeechToText: missing required parameter: opts.token
我的博客帖子有有关IBM Cloud Speech-to-Text的更多信息.
My blog post has more about IBM Cloud Speech-to-Text.
这篇关于带有承载令牌的IBM Cloud语音到文本SDK身份验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!