我如何在Laravel Auth :: attempt中使用条件参数?

时间:2014-07-30 10:28:42

标签: php authentication laravel

使用Laravel 4.1.30我得到以下代码,通过Auth测试登录尝试。

//... more codes here ...

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

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

我喜欢实现条件值,例如:

->active > 0

我使用活动(字段)作为登录用户的身份验证级别。任何高于0(零)的内容都应满足下一个条件。

如何在一个声明中完成?

2 个答案:

答案 0 :(得分:7)

TL;博士

您无法在传递给Auth::attempt()的数组中执行此操作,因为在框架中,硬编码在生成的查询中使用相等比较。

全面审核

框架实施

attempt()功能在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;
}

您可以在此处看到$this->provider->retrieveByCredentials($credentials);的来电。 retrieveByCredentials()函数在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);
    }
}

在这里,您可以看到传递给Auth::attempt()的数组在foreach中处理,并且每个键值对都作为WHERE子句添加到查询中。因为它是通过$query->where($key, $value);调用完成的,所以它仅限于相等比较。

可能的解决方案

解决方法是将此行更改为:

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

然后你可以重构给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);

这个问题是你必须覆盖使用这个数组的所有其他函数,所以你最终得到了一个自定义解决方案。通过这项工作,您可以编写自己的身份验证查询,或在active之后对Auth::attempt()进行检查。

答案 1 :(得分:0)

或者,您也可以按照以下方式快速解决问题

$auth = Auth::attempt(array(
        'email'     => Input::get('email'),
        'password'  => Input::get('password'),
    ), $remember);
    if ($auth) {
                $currentUser = Auth::user();
                if (!($currentUser->status > 0)) {
                    return "invalid_credential";
                }
    }