mallendeo
mallendeo

Reputation: 1517

Best way to make restfull API in Laravel

I'm making a restfull API with Laravel 4 for an external website doing web scraping.

The target site has a login form so each request requires authentication.

If the user want to post or view something, he make a request to my server, that make another request to the target server, get the info, and encodes it in JSON.

My problem is how I get the credentials in my API request? Now I have something like http://myapi.local/login (this make a request to http://externalsite.com/admin/login), POST params are username=test&password=1234 and that returns a session ID

Then for every action, I append the session ID to my api requests http://myapi.local/posts/all?session_id=4D2FtE...

But this is not restfull at all, so the best is to do it with HTTP Basic Auth, that is doing one login for each request

url: http://myapi.local/posts/all

header: Authorization: Basic dGVzdDoxMjM0

and call the login function in my controller.

It's slower because it makes two request to the target site each time, but seems better because I don't save any session or credentials.

How I handle the Authorization header in Laravel? decode base64 and then split credentials?

Is there a better way to do this?

Thank you!

Upvotes: 1

Views: 1489

Answers (1)

Edgar Orozco
Edgar Orozco

Reputation: 2782

Laravel handles basic auth himself, the only thing to do is think where you can use the filter (Laravel handles the basic auth with filters), so:

a) In a route:

Route::get('posts/all', array('before' => 'auth.basic', function()
{
    // Only authenticated users may enter...
}));

b) Constructor in the controller (i prefer this):

function __construct() {
    $this->beforeFilter('auth.basic');
}

Also make this adjust if apply for your case, as laravel docs say:

By default, the basic filter will use the email column on the user record when authenticating. If you wish to use another column you may pass the column name as the first parameter to the basic method in your app/filters.php file:

Route::filter('auth.basic', function()
{
    return Auth::basic('username');
});

Basic Auth Docs

EDITED

In your case then maybe you want implement a custom filter with this two methods as basis.

/**
 * Get the credential array for a HTTP Basic request.
 */
function getBasicCredentials(Request $request, $field)
{
    return array($field => $request->getUser(), 'password' => $request->getPassword());
}
/**
 * Get the response for basic authentication.
 *
 * @return \Symfony\Component\HttpFoundation\Response
 */
function getBasicResponse()
{
    $headers = array('WWW-Authenticate' => 'Basic');
    return new Response('Invalid credentials.', 401, $headers);
}

See the default implementation here:

Upvotes: 2

Related Questions