Skip to content
m3nt0r edited this page Sep 13, 2010 · 7 revisions

There a two flavors: Authed and Un-Authed.

  • Authed means that the user needs to authorize your app to use his data (or work on his behalf).
  • Un-Authed are request available to anyone anytime. Those methods include search and get*-type request.

For Auth there are three stages.

  • Asking for Auth (sending the user to last.fm)
  • Catching the Auth-token (receiving from last.fm)
  • Creating a remote session using the token (signing request)

I start with the simple stuff. A search action in some controller that uses the model which includes the datasource.

Using the API with methods that don’t need auth.

Assuming you have done the above we now just jump right in. Let’s say we want to search for a artists. We would do it like so:

	function searchPeter() {
		$query = 'Peter Gabriel'; // could be $this->data['Lastfm']['query'];
		$results = false;

		$response = $this->Lastfm->Artist('search', array('artist' => $query));
	
		if (!empty($response['Results'])) {
			$results = $response['Results']['Artist']['Artistmatches'];
		} else {
			$this->Session->setFlash('Whoops, no results :-/');
		}

		$this->set('results', $results);
	}

The variable $query holds the value we received from somewhere (a form, etc.). The rest should be self-explaining.

Methods that need auth

Most methods that don’t begin with “get” usually require authentication. The way Last.fm works is that you send the user away from your site to a special page2 where your app details are shown along with two buttons asking the user to allow or deny access to their account3. Once they click allow they will be transferred back to your app along with a random token. This token is required to establish a authenticated session over at Last.fm. Sounds complicated, but it isn’t. The datasource provides a couple handy methods to deal with it.

fn2. It’s either a login screen or a screen with your app description and name.

fn3. They need to authorize your app

h2. Setting up the callback

This is needed if you plan to allow other people to authorize your app. Once you have your action ready you can set it up as callback-url in your Last.fm API account. After the authorize splash screen the user will be taken to this action.

Here is a demo implementation:

	function callback() {		
		try {
			$token = $this->Lastfm->catchToken(); // wait for remote token
			$this->Session->write('lfm_token', $token); // store token

			$response = $this->Lastfm->Auth('getSession'); // create remote user session
			$this->Session->write('lfm_session', $response['Session']); // store remote info locally

			$this->Session->setFlash("You are now logged in via remote session.");

		} catch (LastfmSourceApiException $e) {
			$this->Session->setFlash('API Error: '.$e->getMessage());
		} catch (LastfmSourceException $e) {
			$this->Session->setFlash('DS Error: '.$e->getMessage());

		}

		$this->redirect(array('action' => 'index'));		
	}

We don’t need a view for this action. We just catch, set and redirect.

Tell them where to authorize

Before you can do anything that requires authentication you need to tell your users to authorize your app. This is done with the callback, but the callback is just the second stage. First you need to direct them to the afformentioned special page2. Best thing to do is to create another action called authorize() within the lastfm controller.


function authorize() {
$this→redirect( $this→Lastfm→getLoginUrl() );
}

Now place a link somewhere in your app where you want your user to authorize before proceeding.

Using the API with methods that need auth.

Remember that we stored the token and session locally? In all calls that require auth we need to provide those two in order to sign the request.

Prepare the source

The datasource provides two methods for this: setAuthToken() and setSessionKey(). So before you would call addTags you would call those two first with the info we obtained from the Authorize/Callback process. I would say it’s a good idea to put this into the controller beforeFilter() callback. That way we always have them set when available. If they are actually needed is figured out by the source itself.

	var $token = '';
	var $key = '';
	
	function beforeFilter() {
		if ($this->Session->check('lfm_token')) {
			$this->token = $this->Session->read('lfm_token');
		}
		
		if ($this->Session->check('lfm_session')) {
			$session = $this->Session->read('lfm_session');
			$this->key = $session['key'];
		}
		
		$this->Lastfm->setAuthToken($this->token);
		$this->Lastfm->setSessionKey($this->key);
	}

Actually calling something

Given that we successfully obtained the users session-key and token we can call the API as if you would call a method that doesn’t need auth. In other words.. just like before, only that we can now call everything that’s available.

$this->Model->Artist('addTags', array('artist' => 'Indeep', 'tags' => "disco, 80s, funk, dance, pop"));