1

I have a WordPress running application, which I would like to access using a separate interface that uses Laravel 5.8.(don't worry about the hashing)

As such, instead of cloning passwords back and forth, I would like to use the user_email and user_pass columns in the Laravel User model instead.

I have tried what the official docs say :

namespace App\Http\Controllers;

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

class LoginController extends Controller
{
    /**
     * Handle an authentication attempt.
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return Response
     */
    public function authenticate(Request $request)
    {
        $credentials = $request->only('user_email', 'user_pass');

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

I then edited the blade files, but no avail. Any pointers?

Sujal Patel
  • 2,444
  • 1
  • 19
  • 38
PHPer
  • 637
  • 4
  • 19
  • Are your columns in the users table named `user_email`, and `user_pass`? If so you need to specify them as they are not the defaults. `Auth::attempt(['user_email' => $request->user_email, 'user_pass' => $request->user_pass])`. You will also need to make changes to the User model. https://stackoverflow.com/questions/39374472/laravel-how-can-i-change-the-default-auth-password-field-name – Jeemusu May 23 '19 at 05:08

2 Answers2

3

Laravel provides a way to change the default columns for auth (email, password) by overriding some functions.

In your User model add this function that overrides the default column for password:

App/User.php

/**
 * Get the password for the user.
 *
 * @return string
 */
public function getAuthPassword()
{
    return $this->user_pass;
}

And, in your LoginController change from email to user_email

App/Http/Controllers/Auth/LoginController.php

/**
 * Get the login username to be used by the controller.
 *
 * @return string
 */
public function username()
{
    return 'user_email';
}

Now you have overridden the default columns used by Laravel's Auth logic. But you are not finished yet.

LoginController has a function that validates the user's input and the password column is hardcoded to password so in order to change that, you also need to add these functions in LoginController:

App/Http/Controllers/Auth/LoginController.php

/**
 * Validate the user login request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return void
 *
 * @throws \Illuminate\Validation\ValidationException
 */
protected function validateLogin(Request $request)
{
    $request->validate([
        $this->username() => 'required|string',
        'user_pass' => 'required|string',
    ]);
}


/**
 * Get the needed authorization credentials from the request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
protected function credentials(Request $request)
{
    return $request->only($this->username(), 'user_pass');
}

Next step is to create a custom Provider, let's call it CustomUserProvider that will be used instead of the default one EloquentUserProvider and where you will override the password field.

App/Providers/CustomUserProvider.php

<?php
namespace App\Providers;

class CustomUserProvider extends EloquentUserProvider
{
    /**
     * Retrieve a user by the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByCredentials(array $credentials)
    {
        if (empty($credentials) ||
           (count($credentials) === 1 &&
            array_key_exists('user_pass', $credentials))) {
            return;
        }

        // First we will add each credential element to the query as a where clause.
        // Then we can execute the query and, if we found a user, return it in a
        // Eloquent User "model" that will be utilized by the Guard instances.
        $query = $this->createModel()->newQuery();

        foreach ($credentials as $key => $value) {
            if (Str::contains($key, 'user_pass')) {
                continue;
            }

            if (is_array($value) || $value instanceof Arrayable) {
                $query->whereIn($key, $value);
            } else {
                $query->where($key, $value);
            }
        }

        return $query->first();
    }

    /**
     * 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)
    {
        $plain = $credentials['user_pass'];

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

Now that you extended the default provider you need to tell Laravel to use this one instead of EloquentUserProvider. This is how you can do it.

App/Providers/AuthServiceProvider.php


/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    $this->app->auth->provider('custom', function ($app, $config) {
        return new CustomUserProvider($app['hash'], $config['model']);
    });
}

Finally update the config information config/auth.php and change the driver from eloquent to custom (that's how I named it above; you can change it to whatever you want). So the config/auth.php file should have this bit:

'providers' => [
    'users' => [
        'driver' => 'custom',
        'model' => App\User::class,
    ],
],

Hope it helps!

Regards

Razvan Toader
  • 361
  • 1
  • 3
0

It would be up and working, If you can just use sessions here instead of using Auth::attempt just like working on core PHP.

Maaz Ali
  • 83
  • 5