【问题标题】:IBM Cloud Speech-to-Text SDK auth failures with bearer tokenIBM Cloud Speech-to-Text SDK 身份验证失败,带有不记名令牌
【发布时间】:2020-04-03 23:51:35
【问题描述】:

我正在学习使用Watson Speech JS SDK。我特别喜欢Transcribe from Microphone, with Alternatives。我正在使用 Firebase Cloud Function 生成我的令牌。我使用的是 AngularJS,而不是 JQuery。我遇到的第一个问题是

var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(Object.assign(token, {
          objectMode: true,
          format: false,
          wordConfidence: true
}));

我收到此错误消息:

WatsonSpeechToText: missing required parameter: opts.token

(使用$scope.tokentoken 没有区别。)

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 密钥。

还有其他建议吗?

【问题讨论】:

    标签: ibm-cloud ibm-cloud-speech


    【解决方案1】:

    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 从使用用户名/密码身份验证的 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 令牌上运行的,它可以使用 tokenaccess_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-key 生成的令牌一起使用。或者您的令牌已过期。您可以通过将此代码放入您的应用程序中轻松检查,以告知您的令牌还剩多少分钟:

    // 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 测试您的令牌是否有效。首先获取一个新的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 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 的信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 2016-10-28
      • 1970-01-01
      相关资源
      最近更新 更多