使用 fatsecret food api 时出现 inavlid o_auth 签名错误

问题描述 投票:0回答:5

我的 iPhone 应用程序中遇到了 FatSecret REST api 的无效 oauth 签名问题。以下是回复

error =     {
        code = 8;
        message = "Invalid signature: oauth_signature 'giWu0JtjgG3OBqD_sBCByz-Q2Gk='";
    };

我正在使用 HMAC_SHA1 创建签名请求,对于某些搜索,它会返回正确的签名,在某些情况下,它会针对 food.get 和 food.search 方法给出上述错误

任何帮助都会有用 预先感谢!

iphone oauth error-handling
5个回答
4
投票

我发现使用 FatSecret 进行 oauth 相当乏味。当您向他们发送有关 oauth 问题的电子邮件时,他们会将您引导至他们的 google 群组。最终,我也无法在那里获得太多帮助,但当我最终弄清楚时,我确实发布了我的实现。

这是一个完整的 node.js food.search() 实现——可能值得一看


1
投票

发生这种情况是因为 oauth 签名编码错误。生成的摘要应根据 RFC2045 协议进行 Base64 编码。

通过在生成 o_auth 签名时将出现的字符串“_”替换为“/”,将“-”替换为“+”得到解决方案。

希望它能帮助其他用户:)


0
投票

我发现如果base64编码的oAuth签名有任何空格(RFC3986 url编码后的“+”),我也会收到无效的签名响应。我检查了 oAuth 签名字符串是否包含违规字符,如果包含,我重新生成了 oAuth 签名。我使用 1970 年以来的时间间隔作为时间戳(根据 API 的要求)和随机数,因此重新创建随机数和时间戳直到不存在空格是一个简单的问题。


0
投票
  1. 将请求方式设置为POST。
  2. 输入网址:https://oauth.fatsecret.com/connect/token
  3. 在标题部分中,添加以下标题: 关键:内容类型 值:application/x-www-form-urlencoded
  4. 在“授权”选项卡中,选择“基本身份验证”作为类型。 用户名: 密码:
  5. 在“正文”选项卡中,选择“x-www-form-urlencoded”作为类型。 在正文中添加以下键值对: 键:grant_type 值:client_credentials 添加另一个键值对: 关键:范围 价值:基本

现在,您应该可以在 Postman 中发送请求了。此设置可确保客户端 ID 和客户端密钥作为基本身份验证凭据发送,并且必要的参数包含在请求正文中。

请将 替换为 FatSecret 提供的您的实际客户端 ID 和客户端密钥。


0
投票

我在收到同样的错误时遇到了这篇文章。事实证明,在我的例子中,错误是由于没有在文档中注意到在对签名进行编码之前需要将“&”添加到 API_SECRET 的末尾。为了帮助将来的人,我发布我的解决方案:

import crypto from 'crypto';
import { FS_ID, FS_OA1_API_KEY } from '$env/static/private';
import { v4 as uuidv4 } from 'uuid';

export default class FatSecretOauth1 {
    constructor(httpMethod, url, inputParameters) {
        this.requestUrl = url;
        this.httpMethod = httpMethod.toUpperCase();
        this.inputParameters = {
            ...inputParameters,
            format: 'json',
            oauth_consumer_key: FS_ID,
            oauth_nonce: uuidv4(),
            oauth_signature_method: 'HMAC-SHA1',
            oauth_timestamp: Math.floor(new Date().getTime()),
            oauth_version: '1.0'
        };
        this.paramString = this.buildRequestParameterString();
        this.signature = this.buildSignature();
        return { paramString: this.paramString, signature: this.signature };
    }

    buildSignature() {
        let method = encodeURIComponent(this.httpMethod);
        let url = encodeURIComponent(this.requestUrl);
        let params = encodeURIComponent(this.paramString);
        let signature = crypto
            .createHmac('sha1', `${FS_OA1_API_KEY}&`) //<-- My error was here with the "&"
            .update(`${method}&${url}&${params}`)
            .digest()
            .toString('base64');
        return encodeURIComponent(signature);
    }

    buildRequestParameterString() {
        let params = '';
        Object.entries(this.inputParameters)
            .sort()
            .forEach((cur) => (params += `&${encodeURI(cur[0])}=${encodeURI(cur[1])}`));
        params = params.substring(1);
        return params;
    }
}

下面是使用参数字符串和签名的获取。

const searchByID = {
    method: 'food.get.v4',
    food_id: 27443
};

let url = 'https://platform.fatsecret.com/rest/server.api';
let httpMethod = 'POST';

const result = new FatSecretOauth1(httpMethod, url, searchByID);

const response = await fetch(
`${url}?${result.paramString}&oauth_signature=${result.signature}`,
{
    method: httpMethod
});

  const data = await response.json();

  console.log('fetch Data: ', data);

  return { data: data.food };
}

我希望这可以在将来节省某人的时间。

© www.soinside.com 2019 - 2024. All rights reserved.