为什么在Laravel中进行自定义用户提供程序身份验证后,我获得此"凭据与我们的记录不匹配"消息?

And*_*ili 5 php laravel laravel-5 laravel-5.2 laravel-5.3

我是PHPLaravel的新手.

我正在按照本教程实现自定义用户提供程序:

https://blog.georgebuckingham.com/laravel-52-auth-custom-user-providers-drivers/

我使用的是Laravel 5.3版本.

我简要解释了我的需求:我的Laravel应用程序只是一个前端应用程序,所有业务逻辑(包括用户身份验证)都由暴露REST Web服务Java后端应用程序执行.

拨打电话:

http://localhost:8080/Extranet/login
Run Code Online (Sandbox Code Playgroud)

并通过用户名和密码作为基本身份验证我获得了一个代表已记录用户的JSON响应:

{
  "userName": "Painkiller",
  "email": "painkiller@gmail.com",
  "enabled": true
}
Run Code Online (Sandbox Code Playgroud)

因此,在我的Laravel应用程序中,我必须执行此调用,然后解析先前返回的JSON对象,以将经过身份验证的对象生成到前端应用程序会话中.

我已经实现了上一个教程的所有4个步骤,我认为我已经正确地将用户提供程序替换为执行Web服务调用的自定义用户提供程序,这是我的代码:

它尚未完成,但它似乎工作正常,因为它提交了http:// localhost:8000 /登录页面的Laravel登录表单,它输入到retrieveByCredentials(array $ credentials)方法,并且对我的REST Web服务的调用是正确的执行.

这时候我没有使用插入的凭证,但我只是因为我很懒而且我不想在每次进行测试时在登录表单中插入用户名和密码...

阅读这个官方教程:

https://laravel.com/docs/5.3/authentication#adding-custom-user-providers

它说:

retrieveByCredentials方法接收传递给证书的阵列验证::尝试试图注册到应用程序时的方法.然后,该方法应"查询"与这些凭证匹配的用户的基础持久存储.通常,此方法将在$ credentials ['username']上运行带有"where"条件的查询.然后该方法应返回Authenticatable的实现.此方法不应尝试进行任何密码验证或身份验证.

validateCredentials方法应与$凭证比较给定的$用户对用户进行认证.例如,此方法应该使用Hash :: check将$ user-> getAuthPassword()的值与$ credentials ['password']的值进行比较.此方法应返回true或false,指示密码是否有效.

因此,为简单起见,retrieveByCredentials()方法返回一个模拟的User对象(实现Authenticatable接口).

这是我的代码:

<?php

namespace App\Authentication;

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider;
use GuzzleHttp\Client;
use function GuzzleHttp\json_encode;
use function GuzzleHttp\json_decode;
use Illuminate\Support\Facades\Log;

class UserProvider implements IlluminateUserProvider
{
    public function retrieveById($identifier)
    {
        // TODO: Implement retrieveById() method.
        \Log::info('retrieveById START');

    }

    public function retrieveByToken($identifier, $token)
    {
        // TODO: Implement retrieveByToken() method.
        \Log::info('retrieveByToken START');
    }

    public function updateRememberToken(Authenticatable $user, $token)
    {
        // TODO: Implement updateRememberToken() method.
        \Log::info('updateRememberToken START');
    }

    public function retrieveByCredentials(array $credentials) {

        // TODO: Implement retrieveByCredentials() method.

        \Log::info('retrieveByCredentials START');
        \Log::info('INSERTED USER CREDENTIAL: '.$credentials['email'] . ' ' .$credentials['password']);

        $client = new Client(); //GuzzleHttp\Client

        $response = $client->get('http://localhost:8080/Extranet/login',
            [
                'auth' => [
                    'nobili.andrea@gmail.com',
                    'pswd'
                ]
            ]);

        $dettagliLogin = json_decode($response->getBody());

        \Log::info('response: '.(json_encode($dettagliLogin)));

        $user = new User('Pippo', 'pippo@google.com', true);

        \Log::info('USER: '.(json_encode($user)));

        return $user;


    }

    public function validateCredentials(Authenticatable $user, array $credentials)
    {
        // TODO: Implement validateCredentials() method.
        \Log::info('validateCredentials START');
    }

}
Run Code Online (Sandbox Code Playgroud)

这是返回的User对象的代码(如您所见,它包含JSON从我的Web服务获得的信息):

<?php

namespace App\Authentication;

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\Log;

class User implements Authenticatable {

    private $username;
    private $email;
    private $enabled;

    /**
     * User constructor.
     * @param $username
     * @param $email
     * @param $enabled
     */
    public function __construct($username, $email, $enabled)
    {
        $this->username = $username;
        $this->email = $email;
        $this->enabled = $enabled;
    }


    /**
     * @return string
     */
    public function getAuthIdentifierName() {
        // Return the name of unique identifier for the user (e.g. "id")

    }

    /**
     * @return mixed
     */
    public function getAuthIdentifier() {
        // Return the unique identifier for the user (e.g. their ID, 123)
    }

    /**
     * @return string
     */
    public function getAuthPassword() {
        // Returns the (hashed) password for the user
    }

    /**
     * @return string
     */
    public function getRememberToken() {
        // Return the token used for the "remember me" functionality
    }

    /**
     * @param  string $value
     * @return void
     */
    public function setRememberToken($value) {
        // Store a new token user for the "remember me" functionality
    }

    /**
     * @return string
     */
    public function getRememberTokenName() {
        // Return the name of the column / attribute used to store the "remember me" token
    }

    /**
     * @return mixed
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * @param mixed $username
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * @return mixed
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * @param mixed $email
     */
    public function setEmail($email)
    {
        $this->email = $email;
    }

    /**
     * @return mixed
     */
    public function getEnabled()
    {
        return $this->enabled;
    }

    /**
     * @param mixed $enabled
     */
    public function setEnabled($enabled)
    {
        $this->enabled = $enabled;
    }

}
Run Code Online (Sandbox Code Playgroud)

所以我的retrieveByCredentials()方法返回包含模拟用户信息的User实例,但是我有以下问题:

在登录表单提交后,执行retrieveByCredentials()并返回User实例但我无法访问索引页面,我看到此错误消息:这些凭据与我们的记录不匹配.

在此输入图像描述

根据我的理解,这个错误消息应该参考Laravel标准认证(在DB上),但我绝对不确定这个断言.

这怎么可能?我正在创建一个自定义用户提供程序,其中的retrieveByCredentials()实现了我的自定义逻辑.

怎么了?我错过了什么?如何在我的自定义用户提供程序登录后尝试解决此问题并获取访问权限?

小智 0

您需要根据请求提供表单中的用户名和密码。您可以使用经典的 php 方式或使用 ajax 方式。无论如何,您的后端函数将需要以下代码。

要使用自定义信息登录用户,您可以使用 Auth::attempt。例如:

if(Auth::attempt([
 'username' => $request->username, 
 'password' => $request->password
])){

   # success -> redirect user to home page.
   return redirect()->route('home');

}else{
   # return error.
   $errors = new MessageBag(['password' => ['Email and/or password invalid.']]);

   return redirect()->back()->with(['errors' => $errors]); // For PHP.
   return response()->json(['errors' => $errors]); // For Ajax.
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用 loginUsingId 方法。但首先您必须在数据库中找到用户。

$user = User::where('email', $request->email)->first();

if($user){
 # Check for password match.
 if($request->password == $user->getAuthPassword()){
   Auth::loginUsingId($user->id, true) /*You will have to get user id from database
                                       or to know somehow what user id is. 
                                       Second param (true) is for remembering user.*/
 }
}
else{
  # User does not exist. return error.
}
Run Code Online (Sandbox Code Playgroud)

不要忘记在您的班级中包含班级。

use App\Auth;
use Illuminate\Support\MessageBag;
Run Code Online (Sandbox Code Playgroud)