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_idclient_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 行 107 throw 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 5.6 护照未经身份验证

用户未经授权时的 Laravel 护照自定义错误消息和状态码

laravel passport oauth:客户端错误:`POST http://127.0.0.1:8000 / oauth / token`导致'400 Bad Request`响应:(

api route laravel 总是返回错误 400

致命错误:允许的内存大小为 1610612736 字节用尽 laravel 护照