【问题标题】:Authenticating with Last.fm in Jquery - Invalid method signature supplied在 Jquery 中使用 Last.fm 进行身份验证 - 提供的方法签名无效
【发布时间】:2015-08-06 10:20:18
【问题描述】:

我正在尝试对 Last.fm 会话进行身份验证,并且正在努力正确签署会话密钥请求。

我一直收到Invalid method signature supplied 但是,当我对我认为查询应该包含在 JS 之外的内容进行 md5 哈希处理时,我得到了相同的签名。我猜我必须在字符串中包含错误的数据,但不知道是什么。

我知道还有一些其他问题,我已经将它们全部浏览了一遍,看看这里出了什么问题,但我发誓这对我来说是正确的。

这是签名算法和 Ajax 调用。我也试着留下足够的样本数据。

// Set elsewhere but hacked into this example:
var last_fm_data = {
    'last_token':'TOKEN876234876', 
    'user': 'bob',
    'secret': 'SECRET348264386'
};

// Kick it off.
last_fm_call('auth.getSession', {'token': last_fm_data['last_token']});


// Low level API call, purely builds a POSTable object and calls it. 
function last_fm_call(method, data){  
    // param data - dictionary.

    last_fm_data[method] = false; 
    // Somewhere to put the result after callback.

    // Append some static variables
    data['api_key'] = "APIKEY1323454";
    data['format'] = 'json';
    data['method'] = method;
    post_data = last_fm_sign(data);

    $.ajax({
      type: "post",
      url: last_url,
      data: post_data,
      success: function(res){
          last_fm_data[method] = res;
          console.log(res['key'])// Should return session key.
      },
      dataType: 'json'
     });
}

function last_fm_sign(params){
    ss = "";
    st = [];
    so = {};
    Object.keys(params).forEach(function(key){
        st.push(key); // Get list of object keys
    });
    st.sort(); // Alphabetise it 
    st.forEach(function(std){
        ss = ss + std + params[std]; // build string
        so[std] = params[std];  // return object in exact same order JIC
    });    
        // console.log(ss + last_fm_data['secret']);
        // api_keyAPIKEY1323454formatjsonmethodauth.getSessiontokenTOKEN876234876SECRET348264386
    hashed_sec = unescape(encodeURIComponent($.md5(ss + last_fm_data['secret'])));
    so['signature'] = hashed_sec; // Correct when calculated elsewhere.
    return so; // Returns signed POSTable object
}

任何人都可以看到我在这里失踪了吗?我非常困惑为什么这没有以请求的here 格式返回正确签名的 POSTable 对象。谢谢你的时间。

编辑:如果我没有得到任何建议,我无法感谢任何人的时间!没有人使用过 last.fm 吗?

【问题讨论】:

  • 尝试删除data['format'] = 'json';
  • 谢谢,我会试试这个以及下面的答案。
  • 干杯,虽然有点偏离 - 我在下面用我发现的关于格式属性的内容编辑了我自己的答案。

标签: javascript jquery api md5 last.fm


【解决方案1】:

在调查了您的代码和其他与last.fm api 调用相关的帖子后,我发现@george lee 实际上是正确的。生成auth_sign 时无需提供format

除此之外,您还需要在应用encodeURIComponent()unescape() 函数后将$.md5() 应用到auth_sign 字符串。像这样。

hashed_sec = $.md5(unescape(encodeURIComponent(ss + last_fm_data['secret'])));

另外,在拨打ajax 时,您需要将api_key, token & api_sig 传递为data。但是看到您的代码,表明您正在传递api_key, token, format, method & signature

因此您需要从ajax 调用的data 字段中删除format, method & signature

您需要将api_key, token & api_sig 传递给data 字段。

所以注释data['format'] = 'json'; 行后的最终代码将如下所示。

    // Set elsewhere but hacked into this example:
    var last_fm_data = {
        'last_token':'TOKEN876234876', 
        'user': 'bob',
        'secret': 'SECRET348264386'
    };

    // Kick it off.
    last_fm_call('auth.getSession', {'token': last_fm_data['last_token']});


    // Low level API call, purely builds a POSTable object and calls it. 
    function last_fm_call(method, data){  
        // param data - dictionary.
        last_fm_data[method] = false; 
        // Somewhere to put the result after callback.

        // Append some static variables
        data['api_key'] = "APIKEY1323454";
        //data['format'] = 'json';
        data['method'] = method;

        post_data = last_fm_sign(data);

        $.ajax({
          type: "POST",
          url: last_url,
          data: post_data,
          success: function(res){
              last_fm_data[method] = res;
              console.log(res['key'])// Should return session key.
          },
          dataType: 'json'
         });
    }

    function last_fm_sign(params){
        ss = "";
        st = [];
        so = {};
        so['api_key'] = params['api_key'];
        so['token'] = params['token'];
        Object.keys(params).forEach(function(key){
            st.push(key); // Get list of object keys
        });
        st.sort(); // Alphabetise it 
        st.forEach(function(std){
            ss = ss + std + params[std]; // build string
        });
        ss += last_fm_data['secret'];
            // console.log(ss + last_fm_data['secret']);
            // api_keyAPIKEY1323454formatjsonmethodauth.getSessiontokenTOKEN876234876SECRET348264386
        hashed_sec = $.md5(unescape(encodeURIComponent(ss)));
        so['api_sig'] = hashed_sec; // Correct when calculated elsewhere.
        return so; // Returns signed POSTable object
    }

Please refer to this link.

【讨论】:

  • 谢谢!我会尽快尝试并让您知道结果。我确实在没有单独方法的情况下尝试过,并且绘制了 XML 响应而不是 JSON,但我将尝试使用其他步骤并查看。
  • 遗憾的是还没有机会测试这个。
  • 感谢您的帮助,感谢此处的示例,我发现了我的代码中的错误。
【解决方案2】:

所以在测试了一些响应后,我找到了解决方案。有2个问题。 编辑见下文( 第一个是需要删除

data['format'] = 'json';

正如George Lee 指出的那样。谢谢乔治。 )

另一个问题是我错误地命名了一个变量,因此被发布了错误的名称。线

so['signature'] = hashed_sec;

应该是

so['api_sig'] = hashed_sec;

我在 Pankaj 的回答中注意到了这一点,但不幸的是,他的其余回答(即包括方法)不正确。进行这 2 项更改可解决调用问题并正确签名。

感谢所有建议!

编辑: 玩了一会儿,发现

data['format'] = 'json';

是正确的,但它不会与签名一起被散列。 在散列工作后将data['format'] = 'json'; 添加到 POST 对象,在这种情况下将返回 JSON 而不是 XML - 这是首选方法。在我能找到的任何地方都没有记录在散列后添加,所以你去吧。 新的工作代码如下,这显示了--------------------指示的2行

// Set elsewhere but hacked into this example:
var last_fm_data = {
    'last_token':'TOKEN876234876', 
    'user': 'bob',
    'secret': 'SECRET348264386'
};

// Kick it off.
last_fm_call('auth.getSession', {'token': last_fm_data['last_token']});


// Low level API call, purely builds a POSTable object and calls it. 
function last_fm_call(method, data){  
    // param data - dictionary.

    last_fm_data[method] = false; 
    // Somewhere to put the result after callback.

    // Append some static variables
    data['api_key'] = "APIKEY1323454";
    data['method'] = method;
    post_data = last_fm_sign(data);
    // THEN ADD THE FORMAT ---------------------------------------
    post_data['format'] = 'json';
    $.ajax({
      type: "post",
      url: last_url,
      data: post_data,
      success: function(res){
          last_fm_data[method] = res;
          console.log(res['key'])// Should return session key.
      },
      dataType: 'json'
     });
}

function last_fm_sign(params){
    ss = "";
    st = [];
    so = {};
    Object.keys(params).forEach(function(key){
        st.push(key); // Get list of object keys
    });
    st.sort(); // Alphabetise it 
    st.forEach(function(std){
        ss = ss + std + params[std]; // build string
        so[std] = params[std];  // return object in exact same order JIC
    });    
        // console.log(ss + last_fm_data['secret']);
        // api_keyAPIKEY1323454formatjsonmethodauth.getSessiontokenTOKEN876234876SECRET348264386
    hashed_sec = unescape(encodeURIComponent($.md5(ss + last_fm_data['secret'])));
    so['api_sig'] = hashed_sec; // RENAMED THIS ----------------------------
    return so; // Returns signed POSTable object
}

【讨论】:

  • 是的,我确实在 API 文档中的某处看到它可以作为 JSON 返回,但没有看到任何关于如何做到这一点的地方。很高兴你把这一切都整理好了!
猜你喜欢
  • 1970-01-01
  • 2019-10-30
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2013-05-30
  • 1970-01-01
相关资源
最近更新 更多