1

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!

5
  • @Rafael because it's a restfull API, so it's stateless, no sessions, no cookies ;) Commented Feb 3, 2015 at 3:42
  • Ah ok yes I see you could use WWW-Authenticate response such as WWW-Authenticate: Basic realm="myRealm" Commented Feb 3, 2015 at 3:44
  • @Rafael hmmm I'll try this, it gets the auth credentials with plain php ($_SERVER['PHP_AUTH_USER']), but I was lookin for a builtin Laravel way :P Commented Feb 3, 2015 at 3:46
  • Keep in mind that Auth Basic is using base64 so you will want to secure that TCP connection using SSL Commented Feb 3, 2015 at 3:48
  • 1
    Also for security you might want to put HTTP request connection header to non-persistent. If all you are doing is sending packets of info. This is more secure. By default http connection is persistent, meaning the socket stays open for the connection. You should close and open a socket only when needed. Commented Feb 3, 2015 at 3:52

1 Answer 1

2

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:

Sign up to request clarification or add additional context in comments.

1 Comment

Right! but I'm not using a database at all, I'm just forwarding the request to another domain

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.