5
votes

I am new to PHP and Laravel and I have the following problem.

I know that Laravel provides an ready-to-use login system, created using the statement:

php artisan make:auth

The problem is that this system directly interacts with the database.

My situation is different because my Laravel application implements only the front-end. All of the business logic is handled by a Java back-end application exposing REST web services.

Basically the Laravel front-end application is something like this:

1) A view showing the login form (username and password).

2) A controller class that contains a method that receives the submission from the previous form and then calls the REST web service of the back-end application (sending a request which has an authorization header containing the inserted username and password).

The back-end application will return (into the previous Laravel controller method) a JSON object containing the user information as the response, like this (if the user is authorized)...

{
  "userName": "Painkiller",
  "email": "[email protected]",
  "enabled": true
}

...or, in the case that the user is not authorized, something like this...

{
  "timestamp": 1485183649134,
  "status": 401,
  "error": "Unauthorized",
  "message": "Credenziali non valide",
  "path": "/Extranet/login"
}

My original idea was to write a custom controller that carries out these operations:

  1. The controller handles the login form submission (containing the credentials entered by the user).
  2. The controller calls my back-end web service and obtains a JSON object, if the JSON object represents an authorized user convert it into a PHP model object representing a user.
  3. The controller puts this model object in the session and redirects to the next user page where this information can be retrieved from the session.

I am not so into front-end development but I think that it should work but...I am moving away from Laravel architecture and Laravel logic.

So, my Laravel application can't directly talk with the database but I am thinking that maybe I can try to adopt Laravel architecture.

So I was thinking that in my Laravel project by default I have the \app\Http\Controllers\Auth\LoginController class representing the standard Laravel login system, this one:

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest', ['except' => 'logout']);
    }
}

It contains this line:

use AuthenticatesUsers;

I am not so into PHP, what exactly does this line do? At first, I thought that it added the AuthenticatesUsers functionality to the LoginController but it is more a behavior related to extends and inheritance concept.

Anyway it seems that the AuthenticatesUsers class contains the implementation of the logic to handle the login, this method:

public function login(Request $request)
{
    $this->validateLogin($request);

    // If the class is using the ThrottlesLogins trait, we can automatically throttle
    // the login attempts for this application. We'll key this by the username and
    // the IP address of the client making these requests into this application.
    if ($this->hasTooManyLoginAttempts($request)) {
        $this->fireLockoutEvent($request);

        return $this->sendLockoutResponse($request);
    }

    if ($this->attemptLogin($request)) {
        return $this->sendLoginResponse($request);
    }

    // If the login attempt was unsuccessful we will increment the number of attempts
    // to login and redirect the user back to the login form. Of course, when this
    // user surpasses their maximum number of attempts they will get locked out.
    $this->incrementLoginAttempts($request);

    return $this->sendFailedLoginResponse($request);
}

So I am thinking: can I override this method to perform the call to my web service, obtain the JSON object related to the logged-in user, put this information into the session and redirect to the user page?

Would this be a smart solution for my purpose?

1
AuthenticatesUsers is a trait. You can abstract some functionalities inside a trait. Read more from culttt.com/2014/06/25/php-traitsGayan
You can override it, but I think your case is so specific that it might make sense to create a custom controller, rather than extending the existing one.DevK
@devk Ok...I have also found this other approach to the problem (or it seems to me a possible approach...) instead create a custom controller create a custom authentication driver, this tutorial show what I mean: laravel-recipes.com/recipes/115/… Could be a neater solution?AndreaNobili
Yeah this seems like a really good solution you found!DevK
Hi @AndreaNobili, yes, a custom auth driver is the way. I have also used this method with an external SOAP webservice login.CUGreen

1 Answers

3
votes

You don't have to do so all you have to do is just make your routes and just override the login method or create your own.

Routes :

// authentication routes
Route::get('/login', 'Auth\LoginController@showLoginForm')->name('adminGetLogin');
Route::post('/login', 'Auth\LoginController@login')->name('adminPostLogin');
Route::get('/logout', 'Auth\LoginController@logout')->name('adminLogout');
// reset password routes
Route::get('/password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('showResetForm');
Route::post('/password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('sendResetEmail');
Route::get('/password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('showResetForm');
Route::post('/password/reset', 'Auth\ResetPasswordController@reset')->name('resetPassword');

Web

public function login(Request $request){
    if (! Auth::attempt(['email' => $request->email, 'password' => $request->password, 'is_active' => 1])) {
     // do whatever yo desire

   return redirect('/home');

}

REST API

public function login(Request $request){
    if (Auth::attempt(['email' => $request->email, 'password' => $request->password, 'is_active' => 1])) {
     // do whatever yo desire

    $user = Auth::user();

    return response()->json([
        'Error' => ['type' => 'success', 'desc' => 'Login successful',  'code' => 0],
        'Response' => $user
    ]);

}