简体   繁体   English

发送HTTP POST请求时无效的方法签名

[英]Invalid method signature when sending HTTP POST request

Ok this is really frustrating. 好的,这真的令人沮丧。 I'm using my API key perfectly fine. 我正在使用我的API密钥。 Authentication does just fine, token is generated fine, session key is also OK. 身份验证很好,令牌生成正常,会话密钥也可以。

But when I run the playlist.create , the playlist is not created. 但是当我运行playlist.create ,不会创建播放列表。

I started from almost scratch today, and redid most of my code. 我今天几乎从头开始,并重新编写了大部分代码。 I created 16 playlists successfully, no errors. 我成功创建了16个播放列表,没有错误。 But today, the same code's not working. 但今天,相同的代码不起作用。 I didn't touch it at all and yet the error. 我根本没有触摸它,但错误。

private static void buildPlaylist() {

    String mood = "Happy";
    System.out.println("\nMood is " + mood + "\n\n");

    String title = URLEncoder.encode(mood + " " + new Date().getTime(), "UTF-8");
    String description = URLEncoder.encode("For when you are " + mood + ". Created by MoodicPlayer.", "UTF-8");

    MessageDigest md = MessageDigest.getInstance("MD5");

    String apiSig = "api_key" + key + "description" + description + "methodplaylist.createsk" + sessionKey + "title" + title + secret;
    md.update(apiSig.getBytes());
    byte byteData[] = md.digest();
    //convert the byte to hex format
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < byteData.length; i++) {
        sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
    }
    String hashedSig = sb.toString();

    // FOR DEBUGGING
    System.out.println("api_key = " + key);
    System.out.println("api_sig = " + hashedSig);
    System.out.println("session key = " + sessionKey);
    // FOR DEBUGGING

    String urlParameters = "method=playlist.create&api_key="+ key + "&api_sig=" + hashedSig + "&description=" + description + "&sk=" + sessionKey + "&title=" + title;
    String request = "http://ws.audioscrobbler.com/2.0/";

    URL url = new URL(request);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();     
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setInstanceFollowRedirects(false); 
    connection.setRequestMethod("POST"); 
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
    connection.setRequestProperty("charset", "utf-8");
    connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length));
    connection.setUseCaches(false);

    DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
    wr.writeBytes(urlParameters);
    wr.flush();
    wr.close();

    InputStream is = null;
    Scanner s = null;
    try {
        if (connection.getResponseCode() != 200) {
            s = new Scanner(connection.getErrorStream());
        } else {
            is = connection.getInputStream();
            s = new Scanner(is);
        }
        s.useDelimiter("\\Z");
        String response = s.next();
        System.out.println("\nResponse: " + response + "\n\n");
        BufferedWriter out = new BufferedWriter(new FileWriter("requestCreate.xml"));
        out.write(response);
        out.close();
    } catch (IOException e2) {
        e2.printStackTrace();
    }

    // FOR DEBUGGING
    try {
        System.out.println("Response Code: " + connection.getResponseCode());
        System.out.println("Response Message: " + connection.getResponseMessage()); 
    } catch (IOException e) {
        e.printStackTrace();
    }
    // FOR DEBUGGING
    connection.disconnect();
}

And the output: 并输出:

Starting test for creating playlist...

Mood is Happy
api_key = xxxxx
api_sig = xxxxxx
session key = xxxxx

Response: <?xml version="1.0" encoding="utf-8"?>
<lfm status="failed">
<error code="13">
    Invalid method signature supplied
</error>
</lfm>


Response Code: 403
Response Message: Forbidden

I have checked the code, but cannot find any error. 我检查了代码,但找不到任何错误。 I mean the code was fine 16 hours ago, and suddenly it's not working! 我的意思是16小时前代码很好,突然间它没有用!


For security purposes, I cannot show you my security keys. 出于安全考虑,我无法向您显示我的安全密钥。 However, I did write a quick program to find the last.fm session key: http://github.com/thekarangoel/LastFMSessionKeyFinder Simply register at last.fm/api, enter your API key and secret in the program and you'll have everything you need to test the API call. 但是,我确实编写了一个快速程序来查找last.fm会话密钥: http ://github.com/thekarangoel/LastFMSessionKeyFinder只需在last.fm/api注册,在程序中输入您的API密钥和秘密即可拥有测试API调用所需的一切。

When generating your MD5 hash, you are using the URL encoded versions of your title and description values. 生成MD5哈希时,您使用的是titledescription值的URL编码版本。 The documentation does not say to do that. 文档没有说这样做。 Try using the non-URL-encoded values instead (they do need to be UTF-8 encoded, though). 请尝试使用非URL编码的值(但它们确实需要使用UTF-8编码)。 URL encoding should only be used in actual URL data (hense its name). URL编码只应用于实际的URL数据(hense其名称)。

Try this: 尝试这个:

private static void buildPlaylist() {

    String mood = "Happy";
    System.out.println("\nMood is " + mood + "\n\n");

    String title = mood + " " + new Date().getTime();
    String description = "For when you are " + mood + ". Created by MoodicPlayer.";

    MessageDigest md = MessageDigest.getInstance("MD5");

    String apiSig = "api_key" + key + "description" + description + "methodplaylist.createsk" + sessionKey + "title" + title + secret;
    md.update(apiSig.getBytes("UTF-8"));
    byte byteData[] = md.digest();
    //convert the byte to hex format
    StringBuffer sb = new StringBuffer(byteData.length*2);
    for (int i = 0; i < byteData.length; i++) {
        sb.append(String.format("%02X", byteData[i]));    
    }
    String hashedSig = sb.toString();

    // FOR DEBUGGING
    System.out.println("api_key = " + key);
    System.out.println("api_sig = " + hashedSig);
    System.out.println("session key = " + sessionKey);
    // FOR DEBUGGING

    String urlParameters = "method=playlist.create&api_key="+ key + "&api_sig=" + hashedSig + "&description=" + URLEncoder.encode(description, "UTF-8") + "&sk=" + sessionKey + "&title=" + URLEncoder.encode(title, "UTF-8");
    String request = "http://ws.audioscrobbler.com/2.0/";

    URL url = new URL(request);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();     
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setInstanceFollowRedirects(false); 
    connection.setRequestMethod("POST"); 
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
    connection.setRequestProperty("charset", "utf-8");
    connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length));
    connection.setUseCaches(false);

    DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
    wr.writeBytes(urlParameters);
    wr.flush();
    wr.close();

    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM