【问题标题】:Laravel Passport password grant returns Invalid Credentials ExceptionLaravel Passport 密码授予返回 Invalid Credentials 异常
【发布时间】:2017-03-27 00:24:42
【问题描述】:

我正在尝试设置一个使用受 Passport 保护的 Laravel API 的 SPA。

我首先为此专门创建了一个新的 Laravel 应用程序,然后按照说明设置护照并设置密码授予客户端。

我可以成功创建一个新用户,将用户保存到数据库,并登录用户。之后,我尝试使用新创建的用户信息以及密码授予客户端 ID 和密码来创建访问令牌.此时我收到异常。

我通读了日志,看到了异常被抛出的位置。在League\OAuth2\Server\Grant\PasswordGrant 内部,validateUser 方法有以下内容:

if ($user instanceof UserEntityInterface === false) {
            $this->getEmitter()->emit(new RequestEvent(RequestEvent::USER_AUTHENTICATION_FAILED, $request));

            throw OAuthServerException::invalidCredentials();
        }

看到这一点,我在我的用户模型上实现了UserEntityInterface 并实现了getIdentifier 方法,但我仍然收到异常。我真的不太确定从这里去哪里,任何帮助将不胜感激。下面是我的一些代码。

这是我的注册控制器:

class RegisterController extends Controller
{

    private $tokenService;


    public function __construct(AccessTokenService $tokenService)
    {
        //$this->middleware('guest');
        $this->tokenService = $tokenService;
    }

    public function register(Request $request)
    {
        $this->validateWith($this->validator($request->all()));
        Log::debug('Validated');

        $user = $this->create($request->all());
        $this->guard()->login($user);
        $this->tokenService->boot(Auth::user());

        return response()->json($this->tokenService->getNewAccessToken(), 200);
    }

    protected function guard()
    {
        return Auth::guard();
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|min:6|confirmed',
            'password_confirmation' => 'required'
        ]);
    }

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }
}

这些是 AccessTokenService 的相关部分:

public function getNewAccessToken() {
        $http = new Client();
        $client = \Laravel\Passport\Client::where('id', 6)->first();

        Log::debug($client->getAttribute('secret'));
        Log::debug($this->user->getAttribute('email'));
        Log::debug($this->user->getAuthPassword());

        $response = $http->post('homestead.app/oauth/token', [
            'form_params' => [
                'grant_type' => 'password',
                'client_id' => 6,
                'client_secret' => $client->getAttribute('secret'),
                'username' => $this->user->getAttribute('email'),
                'password' => $this->user->getAuthPassword(),
                'scope' => '*'
            ]]);
        unset($client);
        $status = $response->getStatusCode();
        $body = $response->getBody();

        Log::debug($body->getContents());
        Log::debug($status);

        switch($status)
        {
            case 200:case 201:
            case 202:
                $tokens = array(
                    "user_id" => $this->user->getAttribute('id'),
                    "access_token" => $body['access_token'],
                    "refresh_token" => $body['refresh_token']
                );
                $output = ["access_token" => $this->storeTokens($tokens), 'status_code' => $status];
                break;
            default:
                $output = ["access_token" => '', 'status_code' => $status];
                break;

        }
        return $output;
    }

    private function storeTokens(array $tokens) {
        UserToken::create([
            "user_id" => $tokens['user_id'],
            "access_token" => bcrypt($tokens['access_token']),
            "refresh_token" => bcrypt($tokens['refresh_token'])
        ]);
        return $tokens['access_token'];
    }

【问题讨论】:

  • 发布您收到的异常消息。
  • 您是在本地使用 api 吗? (IE的SPA部分是同一个应用吗?)
  • 是的,我在本地使用 API。我解决了这个问题。我在请求 access_token 时传递了散列密码,而 PasswordGrant 需要一个未散列的密码。现在都修好了。

标签: php laravel-5


【解决方案1】:

所以我发现了这个问题。当我请求访问令牌时,我传递了用户的电子邮件和密码,但是当我需要传递未散列的密码时,我传递了散列密码。

我对访问令牌的请求如下所示:

$response = $http->post('homestead.app/oauth/token', [
            'form_params' => [
                'grant_type' => 'password',
                'client_id' => 6,
                'client_secret' => $client->getAttribute('secret'),
                'username' => $this->user->getAttribute('email'),
                'password' => $this->user->getAuthPassword(), //Here is the problem
                'scope' => '*'
            ]]);

通过使用这样的未哈希密码将请求传递给函数解决了问题:

$response = $http->post('homestead.app/oauth/token', [
            'form_params' => [
                'grant_type' => 'password',
                'client_id' => 6,
                'client_secret' => $client->getAttribute('secret'),
                'username' => $request['email'],
                'password' => $request['password'],
                'scope' => '*'
            ]]);

【讨论】:

    【解决方案2】:

    就我而言,这很神奇

    当我将用户名从电子邮件格式更改为简单(仅限字母数字)格式时,它可以工作。 如果有人对我的案子有意见,请告诉原因。

    谢谢

    【讨论】:

      猜你喜欢
      • 2018-02-01
      • 2014-06-10
      • 1970-01-01
      • 2021-08-12
      • 2018-11-23
      • 2019-03-31
      • 1970-01-01
      • 2020-02-26
      • 1970-01-01
      相关资源
      最近更新 更多