Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I sign requests reliably for the Last.fm api?

Tags:

c#

linq

md5

I'm trying to implement authorization through Last.fm. I'm submitting my arguments as a Dictionary to make the signing easier. This is the code I'm using to sign my calls:

public static string SignCall(Dictionary<string, string> args)
{
    IOrderedEnumerable<KeyValuePair<string, string>> sortedArgs = args.OrderBy(arg => arg.Key);
    string signature = 
        sortedArgs.Select(pair => pair.Key + pair.Value).
        Aggregate((first, second) => first + second);
    return MD5(signature + SecretKey);
}

I've checked the output in the debugger, it's exactly how it should be, however, I'm still getting WebExceptions every time I try, meaning the API is returning "Invalid Method Signature". This means it's not accepting the signature SignCall is generating.

Here's my code I use to generate the URL in case it'll help:

public static string GetSignedURI(Dictionary<string, string> args, bool get)
{
    var stringBuilder = new StringBuilder();
    if (get)
        stringBuilder.Append("http://ws.audioscrobbler.com/2.0/?");
    foreach (var kvp in args)
        stringBuilder.AppendFormat("{0}={1}&", kvp.Key, kvp.Value);
    stringBuilder.Append("api_sig="+SignCall(args));
    return stringBuilder.ToString();
}

And sample usage to get a SessionKey:

var args = new Dictionary<string, string>
                       {
                           {"method", "auth.getSession"},
                           {"api_key", ApiKey},
                           {"token", token}
                       };
string url = GetSignedURI(args, true);

EDIT:

Oh, and the code references an MD5 function implemented like this:

public static string MD5(string toHash)
{
    byte[] textBytes = Encoding.UTF8.GetBytes(toHash);
    var cryptHandler = new System.Security.Cryptography.MD5CryptoServiceProvider();
    byte[] hash = cryptHandler.ComputeHash(textBytes);
    return hash.Aggregate("", (current, a) => current + a.ToString("x2"));
}

Also, here's the API documentation: API - Last.fm, with this page detailing authorization.

like image 876
Arda Xi Avatar asked May 09 '10 02:05

Arda Xi


People also ask

Does Last FM have an API?

The Last.fm API allows anyone to build their own programs using Last.fm data. Find out more about how you can plug directly into our vast database or browse the list of methods on the left.

How do I create an API account on Last FM?

CREATING YOUR LAST.FM API KEY Click on the Register button (or Login if you already have an account). Once the account is created and activated (you receive an email to activate the account after creation) go to this address:https://www.last.fm/api & click on the link Get an API account.

Is Last fm API free?

Working with the Last.fm APIThey provide free access to their API so that music services can send them data, but also provide endpoints that summarize all the data that Last.fm has on various artists, songs, and genres.

Where is my last FM API key?

Obtaining an API key Go to http://www.last.fm/api. Click on the link "Get an API account". Login to last.fm if you have an account there. Optionally you may login using your Facebook account.


1 Answers

Your code works fine to me. What I did:

  1. Get the token: http://ws.audioscrobbler.com/2.0/?method=auth.gettoken&api_key=677626cfada7f04fa80cfd3ad199b109, the token returned was 53c8890afbbf94281931cd11bf28a4e0
  2. Authenticate that token with user: http://www.last.fm/api/auth?api_key=677626cfada7f04fa80cfd3ad199b109&token=53c8890afbbf94281931cd11bf28a4e0
  3. Use your code to get URL and then download its contents using WebClient, which returned user name and session key.
like image 184
svick Avatar answered Oct 30 '22 07:10

svick