Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i use conditional parameters in Laravel Auth::attempt?

Using Laravel 4.1.30 I got this following code which test a sign-in attempt via Auth.

//... more codes here ...

$auth = Auth::attempt(array(
    'email'     => Input::get('email'),
    'password'  => Input::get('password'),
    'active'    => 1
), $remember);

if ($auth) {
    //... more codes here ...
}

I like to implement a conditional value such as:

->active > 0

I am using the active (field) as a level of authentication for users signing in. Anything above 0 (zero) should satisfy the next condition.

How can it be done in one statement?

like image 903
Ace Caserya Avatar asked Jul 30 '14 10:07

Ace Caserya


People also ask

What is Auth :: Routes () in Laravel?

Auth::routes() is just a helper class that helps you generate all the routes required for user authentication. You can browse the code here https://github.com/laravel/framework/blob/5.3/src/Illuminate/Routing/Router.php instead.

What does attempt do in Laravel?

The attempt method accepts an array of key / value pairs as its first argument. The password value will be hashed. The other values in the array will be used to find the user in your database table. So, in the example above, the user will be retrieved by the value of the email column.

How do you use AUTH command in Laravel?

Introduction. Want to get started fast? Install the laravel/ui Composer package and run php artisan ui vue --auth in a fresh Laravel application. After migrating your database, navigate your browser to http://your-app.test/register or any other URL that is assigned to your application.

How do I change the login function in Laravel Auth?

In the user login controller in the login module, there are the following codes: $loggedIn = $this->auth->login( [ 'email' => $request->email, 'password' => $request->password, ], (bool) $request->get('remember_me', false) );


1 Answers

tl;dr

You can't do this within the array passed to Auth::attempt(), because in the framework it is hard coded to use equality comparison in the generated query.

Full review

Framework implementation

The attempt() function is implemented in Illuminate/Auth/Guard.php.

public function attempt(array $credentials = array(), $remember = false, $login = true)
{
    $this->fireAttemptEvent($credentials, $remember, $login);

    $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

    // If an implementation of UserInterface was returned, we'll ask the provider
    // to validate the user against the given credentials, and if they are in
    // fact valid we'll log the users into the application and return true.
    if ($this->hasValidCredentials($user, $credentials))
    {
        if ($login) $this->login($user, $remember);

        return true;
    }

    return false;
}

Here you can see a call for $this->provider->retrieveByCredentials($credentials);. The retrieveByCredentials() function is implemented in Illuminate/Auth/DatabaseUserProvider.php.

public function retrieveByCredentials(array $credentials)
{
    // 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
    // generic "user" object that will be utilized by the Guard instances.
    $query = $this->conn->table($this->table);

    foreach ($credentials as $key => $value)
    {
        if ( ! str_contains($key, 'password'))
        {
            $query->where($key, $value);
        }
    }

    // Now we are ready to execute the query to see if we have an user matching
    // the given credentials. If not, we will just return nulls and indicate
    // that there are no matching users for these given credential arrays.
    $user = $query->first();

    if ( ! is_null($user))
    {
        return new GenericUser((array) $user);
    }
}

Here you can see that the array you pass to Auth::attempt() is processed in a foreach and every key-value pairs are added as a WHERE clause to the query. Because it done with a $query->where($key, $value); call, it is limited to equality comparison.

Possible solutions

A workaround would be to change this line to something like:

$query->where($key, $value['operator'], $value['value']);

Then you could restructure the array given to Auth::attempt().

$auth = Auth::attempt(array(
    'email' => array(
        'value'    => Input::get('email'),
        'operator' => '='
    ),
    'password' => array(
        'value'    => Input::get('password'),
        'operator' => '='
    ),
    'active' => array(
        'value'    => 0,
        'operator' => '>'
    )
), $remember);

The problem with this is that you have to override every other function that uses this array, so you end up with a custom solution. With this effort you could write your own authentication query or do a check on active after Auth::attempt().

like image 76
totymedli Avatar answered Sep 24 '22 23:09

totymedli