Laravel 5.5 API authentication without Passport

I had the task to implement an JSON API Authentication in Laravel. In my project concerns about performance or extensibility were no topic. So I thought I’ll try the „basic“ authentication methods Laravel offers.

As Laravel developers could imagine, the problem here is that responses of login requests, regardless of successful or not, contain either the full view home or login (with errors). But for my JSON API I’d rather receive, well JSON responses that contain „success“ or „error“. Here’s how I solved this:

Create new API Routes

In the routes/web.php (not in api.php, because these use middleware „api“) I added routes for login via API:

Route::post('api/login', 'LoginControllerAPI@login')->name('api.login');
Route::post('api/logout', 'LoginControllerAPI@logout')->name('api.logout');

Create the LoginControllerAPI

Because I still want to use the project conventionally in the browser as well as via JSON API I cannot modify the default controller Auth/LoginController.php. So I created a new Controller , like you can see in the routes. Then I copied all the content of class Auth/LoginController.php into our API controller.

To adjust login for my API I override the functions sendLoginResponse(Request $request) and sendFailedLoginResponse(Request $request) and logout(Request $request), because after the login/logout is done they return a redirect response, but I’d rather have JSON.
To make it possible to still access the the base functions of trait AuthenticatesUsers I gave these functions aliases:

class LoginControllerAPI extends Controller {
  // Give functions of trait aliases (to override but still usable). 
  use AuthenticatesUsers {
    sendLoginResponse as protected _sendLoginResponse;
    sendFailedLoginResponse as protected _sendFailedLoginResponse;
    logout as protected _logout;
  }

  protected function sendLoginResponse(Request $request) {
    $this->_sendLoginResponse($request);
    // Drop default redirect reponse
    return response()->json([ 'msg'  => 'Login successful.', ]);
  }

  protected function sendFailedLoginResponse(Request $request) {
    return response()->json([ 'error' =>   trans('auth.failed'), ]);
  }
}

The CSRF token

Now we lack the CSRF token to secure the login attempts. I simply added a GET function in our LoginControllerAPI.

The route in routes/web.php:

Route::get('api/csrf', 'LoginControllerAPI@csrf')->name('api.csrf'); 

And the function csrf() in the controller:

public function csrf() {
  return response() ->json([ 
    'csrf_token' => csrf_token()
  ]);
}

Login using jQuery

Now you login sending JSON requests for example with jQuery:

// Get CSRF token 
$.get('/api/csrf')
  .done(function( data ) {
    const token = data.csrf_token;
    console.log( "Received token: " + token  );
    // Got CSRF token; now send login request 
    $.post('/api/login', {email: 'test@test.de', password: '123456', _token: token})
    .done(function(data) {
      console.log('Received login RESPONSE: ' + JSON.stringify( data ) );
    });
  });

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.