Laravel 6 护照在错误的凭证上返回 400 Bad request
Posted
技术标签:
【中文标题】Laravel 6 护照在错误的凭证上返回 400 Bad request【英文标题】:Laravel 6 passport returns 400 Bad request on wrong credential 【发布时间】:2020-04-01 10:36:22 【问题描述】:我将 Laravel 6 护照 grant password 用于我的 Vue 后端。
当我向 oauth/token 发送正确的凭据时,它可以工作并返回令牌,但是当我发送错误(电子邮件/密码)时,它会返回 400 而不是 401 并显示此消息。
"error": "invalid_grant",
"error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.",
"hint": "",
"message": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
我检查了 client_id 和 client_secret。
我用新安装的 Laravel + passport 测试,没有一行代码,Laravel 5.8 返回 401 没有任何问题,但 Laravel 6 返回 400 错误请求。
你有什么想法吗?
【问题讨论】:
401 未经授权,不是“错误的凭据” 我知道,但是在 Laravel 5.8 中,当我提供错误的用户名/密码时,它会返回 401 并显示以下消息:invalid_credentials(用户凭据不正确),但在 Laravel 6 中,它会返回 400 并显示 invalid_grant 消息 @AlbertoSinigaglia 您是否使用 artisan 中的--password
标志创建了您的客户端对?
根据 Laravel 网站“如果您已经运行了 passport:install 命令,则不需要运行此命令”,但是是的,我删除了它们并使用 --password 标志创建了新客户端。 @mdexp
我也遇到了同样的问题,你找到解决办法了吗?
【参考方案1】:
试试这个:
php artisan passport:keys --force
php artisan passport:client --password
然后编辑您的.env
PASSPORT_CLIENT_ID="Client ID"
PASSPORT_CLIENT_SECRET="Client secret"
【讨论】:
【参考方案2】:更新 UserFactory 密码(使用 Hash::make() 而不是 bcrypt)
【讨论】:
【参考方案3】:我不得不在 laravel 7.x 中使用以下内容将 app/Exceptions/Handler.php
中的 400 级别错误转换为 401
注意:检查OAuthServerException::class
类型
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Throwable $exception)
if (get_class($exception) === \Laravel\Passport\Exceptions\OAuthServerException::class)
return response(['message' => $exception->getMessage()], 401);
return parent::render($request, $exception);
【讨论】:
【参考方案4】:您可以在 App\Exceptions\Handler
上添加错误处理程序use League\OAuth2\Server\Exception\OAuthServerException;
class Handler extends ExceptionHandler
public function render($request, Exception $exception)
if (get_class($exception) === OAuthServerException::class)
response()->json(['message' => $exception->getMessage()], 401);
【讨论】:
纠正use Laravel\Passport\Exceptions\OAuthServerException
【参考方案5】:
我终于找到了问题,问题又回到了 Laravel 护照使用的 league/oauth2-server。
他们在版本 8 中将响应从 401 更改为 400。
PR link
我把登录部分的代码改成了这个。
switch ($e->getCode())
case 400:
case 401:
return response()->json('Your credentials are incorrect. Please try again', $e->getCode());
break;
default:
return response()->json('Something went wrong on the server', $e->getCode());
【讨论】:
我改用了自己的代码,“我们通常不会更改供应商文件...”,但如果您想知道更改 vendor/league/oauth2-server/src/Grant/ 的位置在哪里PasswordGrant.php 行 107throw OAuthServerException::invalidGrant();
更改为 throw OAuthServerException::invalidCredentials();
@azurecorn
我面临同样的问题。你知道这是一个已知问题还是抛出异常的新方法?您的解决方案实际上并不代表真正的响应,因为您将无法显示“嘿!完整的登录数据!”或“嘿!您的数据有误!”
似乎是新方式,关于这个文档https://tools.ietf.org/html/rfc6749#section-5.2
应该是400。如果您想将错误的凭据与错误分开,您可以通过验证用户名和密码然后$user->createToken('tokenName')->accessToken
@Luciano 手动创建令牌
这是正确的@Mojtaba Sayari,由github.com/thephpleague/oauth2-server/issues/1093 的创作者确认,顺便说一句,感谢您提供可能的解决方案
我建议您使用 abort 而不是响应:abort($response->status(), 'Your credentials are incorrect. Please try again')
以上是关于Laravel 6 护照在错误的凭证上返回 400 Bad request的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 护照抛出错误:“在 null 上调用成员函数 createToken()”
用户未经授权时的 Laravel 护照自定义错误消息和状态码
laravel passport oauth:客户端错误:`POST http://127.0.0.1:8000 / oauth / token`导致'400 Bad Request`响应:(