【问题标题】:Why Laravel Auth::guard()->attempt() isn't working?为什么 Laravel Auth::guard()->attempt() 不起作用?
【发布时间】:2022-01-26 06:40:23
【问题描述】:

所以基本上我在付款后生成用户数据,它保存在我创建的表中,它有一个用户名和一个使用 Hash::make() 方法的加密密码。

我想做的是使用存储在数据库中的数据登录,所以我做了一个守卫。

这是带有保护的auth.php 文件:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'plataforma' => [
        'driver' => 'session',
        'provider' => 'usuario',
    ],
],

这些是提供者:

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
    'usuario' => [
        'driver' => 'eloquent',
        'model' => App\Models\Usuario::class,
    ],

这是模型:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;


class Usuario extends Authenticatable
{
    use HasFactory;
    use Notifiable;

    protected $guard = 'plataforma';

    protected $fillable = [
        'nombre_usuario', 'correo', 'clave',
    ];

    protected $hidden = [
        'clave', 'remember_token',
    ];
}

最后是控制器:

namespace App\Http\Controllers;

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

class PlataformaController extends Controller
{
    public function login()
    {
        return view('web.plataforma-login');
    }

    public function autenticar(Request $request)
    {
        if (Auth::guard('plataforma')->attempt(['nombre_usuario' => $request->input('nombre_usuario'), 'clave' => $request->input('clave')])) {
            return view('web.plataforma');
        } else {
            dd(Auth::guard('plataforma')->attempt(['nombre_usuario' => $request->input('nombre_usuario'), 'clave' => $request->input('clave')]));
        }
    }

    public function dashboard()
    {
        return view('web.plataforma');
    }
}

所以基本上 Auth::guard('plataforma')->attempt(...) 返回 false,我已经检查了 $request->input(...) 的值是否正确,我检查了DB中的加密密码和用户用Hash::check()输入的密码是一样的,所以不知道哪里错了,好迷茫……

我花了很多时间阅读其他问题也没有解决方案,如果有人可以帮助我,我会很高兴。

【问题讨论】:

  • 您的意思是您想使用从数据库获取的凭据进行自动登录?
  • 我认为这与您选择的键名有关。 password 似乎是硬编码的

标签: php laravel


【解决方案1】:

阅读 API 后,我得出结论 attempt() 对您不起作用,因为您使用了不同的密码列名称。

以下是Illuminate\Auth\SessionGuard 类中的attempt 函数代码:

/**
 * Attempt to authenticate a user using the given credentials.
 *
 * @param  array  $credentials
 * @param  bool  $remember
 * @return bool
 */
public function attempt(array $credentials = [], $remember = false)
{
    $this->fireAttemptEvent($credentials, $remember);

    $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)) {
        $this->login($user, $remember);

        return true;
    }

    // If the authentication attempt fails we will fire an event so that the user
    // may be notified of any suspicious attempts to access their account from
    // an unrecognized user. A developer may listen to this event as needed.
    $this->fireFailedEvent($user, $credentials);

    return false;
}

这里的关键函数是retrieveByCredentialshasValidCredentials

这是来自Illuminate\Auth\EloquentUserProviderretrieveByCredentials。如您所见,它从 foreach 的查询中排除了 'password' 键。

/**
 * 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 &&
        → Str::contains($this->firstCredentialKey($credentials), 'password'))) { ←
        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->newModelQuery();

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

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

    return $query->first();
}

这是来自Illuminate\Auth\EloquentUserProviderhasValidCredentials。这里的关键函数是validateCredentials

/**
 * Determine if the user matches the credentials.
 *
 * @param  mixed  $user
 * @param  array  $credentials
 * @return bool
 */
protected function hasValidCredentials($user, $credentials)
{
    $validated = ! is_null($user) && $this->provider->validateCredentials($user, $credentials);

    if ($validated) {
        $this->fireValidatedEvent($user);
    }

    return $validated;
}

这是来自Illuminate\Auth\EloquentUserProvider 类的validateCredentials。您可以再次看到它,默认使用 'password' 作为键名。让我们看看getAuthPassword() 长什么样子。

/**
 * 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['password']; ←

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

最后是来自Illuminate\Auth\Authenticatable 类的getAuthPassword。它只是返回模型的'password' 属性。

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



基本上,如果您想让它工作,您需要更改您的代码的一些内容。

  1. 使用password 作为attempt() 中的键
public function autenticar(Request $request)
{
    $attempt = Auth::guard('plataforma')->attempt([
        'nombre_usuario' => $request->input('nombre_usuario'),
        'password' => $request->input('clave')
    ]);

    if ($attempt) {
        return view('web.plataforma');
    } else {
        dd($attempt);
    }
}
  1. 覆盖可验证模型 (Usuario) 的 getAuthPassword 方法。
# Usuario model
/**
 * Get the password for the user.
 *
 * @return string
 */
public function getAuthPassword()
{
    return $this->clave;
}

【讨论】:

    猜你喜欢
    • 2013-02-27
    • 2014-12-17
    • 1970-01-01
    • 2017-03-31
    • 2016-05-17
    • 2017-01-06
    • 2018-02-27
    • 2017-03-10
    相关资源
    最近更新 更多