Switch88
Switch88

Reputation: 130

Laravel 7 authentication attempt

From Laravel 7.x documentation, I'm trying to create a manual authentication for my application. The documentation shows as following:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function authenticate(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (Auth::attempt($credentials)) {
            // Authentication passed...
            return redirect()->intended('dashboard');
        }
    }
}

I have my own user's table:

sys_users
==========
user_acc character varying(20) NOT NULL, -- Primary Key
full_name character varying(300) NOT NULL,
is_suspended boolean DEFAULT FALSE,
CONSTRAINT PK_SysUsers PRIMARY KEY (user_acc),

To login, the user need to enter the following data:

I tried to customize the controller a bit (not completed yet):

class LoginController extends Controller
{
    public function authenticate(Request $request)
    {
        $request->validate([
            'username' => 'required',
            'password' => 'required',
        ]);
        
        $credentials = $request->only('username', 'password', 'module');

        if (Auth::attempt($credentials)) {
            return redirect()->route($request->module);
        }
    }
}

What I want to add to the customized code above is: (i) checking if the username is exist in the table by querying the sys_users table, (ii) checking the password using POP3 (I already prepared the phpmailer library and the code), and (iii) checking if the user has access to those module by querying another table that I had prepared.

The problem is:

  1. I don't know WHERE to put all of that code. If possible, I wanted to put them inside the Auth class' attempt method, but I can't seem to find the supposed method. The documentation is very lacking and did not provide a detailed explanation.
  2. IF somehow it is impossible to modify the attempt method in Auth class, how should I proceed with the authentication process?

Upvotes: 2

Views: 1571

Answers (1)

Kurt Friars
Kurt Friars

Reputation: 3764

What you are looking to do is implement your own user provider to verify your users credentials using an external POP3 email system.

I don't believe you need to customize your Guard, as I am assuming you still would like the StatefulGuard of the default SessionGuard which will check and store information about the state of authentication in the session.

I think you likely want all other default behavior, aside from how you are validating the credentials provided.

Perhaps in the ./app/Providers/ folder you can create:

PopThreeUserProvider.php

namespace App\Providers;

use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;

class PopThreeUserProvider extends EloquentUserProvider
{
    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials)
    {
        // Implement your pop3 authentication here, I have left the default code
        // for the Eloquent provider below
        $plain = $credentials['password'];

        return $this->hasher->check($plain, $user->getAuthPassword());
    }
}

Now in your ./app/Providers/AuthServiceProvider.php

class AuthServiceProvider extends ServiceProvider
{
    ...

    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        ...

        Auth::provider('pop3', function ($app, array $config) {
            return new PopThreeUserProvider($app->make('hash'), $config['model']);
        });

        ...
    }

    ...
}

Now in your config/auth.php:

    ...

    'providers' => [
        'users' => [
            'driver' => 'pop3',
        ],
    ],

    ...

Of course this all assumes you have:

class User extends Authenticatable
{
    protected $table = 'sys_users';
    protected $primaryKey = 'user_acc';
    protected $incrementing = false;
    ...

Upvotes: 1

Related Questions