Laravel Passport:发送令牌请求时的附加模型条件

Posted

技术标签:

【中文标题】Laravel Passport:发送令牌请求时的附加模型条件【英文标题】:Laravel Passport : Additional Model Conditions while sending Token Request 【发布时间】:2017-05-17 06:09:55 【问题描述】:

我正在使用 Password Grant Tokens 为移动应用程序构建 API。当用户尝试登录应用程序时,客户端会发送访问令牌请求。

用户可能没有使用发送到他的电子邮件的链接验证他的帐户。我希望在查询中添加一个附加条件并相应地提供错误响应。目前,由于 Passport 管理令牌部分,我不能直接这样做。

如何解决?如果用户帐户有任何问题,我如何潜入令牌请求并发送自定义响应?否则继续发送令牌。

【问题讨论】:

如果我的回答对您有帮助,请将其标记为已接受以关闭此线程。谢谢。 【参考方案1】:

在将输入数据发送到您的身份验证服务提供商之前添加一个中间件,并根据您的数据库检查传入的电子邮件。如果电子邮件已通过验证,则通过将其发送给身份验证服务提供商来继续请求,否则返回错误响应以及您想要的任何自定义消息。

我看到人们仍在寻找这个答案并来到这个页面。定义自己的 oauth/token 路由可能是一种方法,但如果您使用为此目的而制作的 middleware 在将数据发送到控制器之前进行更改,则它更合乎逻辑。

制作中间件:php artisan make:middleware MyMiddleware

内核中注册您的中间件,并在您的身份验证中间件之前进行注册

protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,//auth middleare
        'your_middleware_identifier'=>\App\Http\Middleware\MyMiddleware::class,
    ];


    /**
     * The application's middleware priority array.
     *
     * These middlewares will be executed in way they are listed.
     *
     * @var array
     */
    protected $middlewarePriority = [
        \App\Http\Middleware\MyMiddleware::class,
        \Illuminate\Auth\Middleware\Authenticate::class,
    ];

最后,您可以在 AuthServiceProvider.php 文件中使用您的中间件,您的护照路线是: 在 boot() 函数中

public function boot(Request $request)
    
        $this->registerPolicies();

        Route::group(['middleware' => 'your_middleware_identifier'], function () 
            Passport::routes();
        );
    

希望对你有帮助

【讨论】:

【参考方案2】:

来自 Laravel 贡献者的回答:

制作自己的 oauth/token 路由并将其放入 /routes 内的 oauth.php 文件中:

Route::post('/oauth/token', [
    'uses' => 'Auth\CustomAccessTokenController@issueUserToken'
]);

制作一个 CustomAccessTokenController.php

<?php

namespace App\Http\Controllers\Auth;

use Psr\Http\Message\ServerRequestInterface;
use Laravel\Passport\Http\Controllers\AccessTokenController;

class CustomAccessTokenController extends AccessTokenController

    /**
     * Hooks in before the AccessTokenController issues a token
     *
     *
     * @param  ServerRequestInterface $request
     * @return mixed
     */
    public function issueUserToken(ServerRequestInterface $request)
    
        $httpRequest = request();

        // 1.
        if ($httpRequest->grant_type == 'password') 
            // 2.
            $user = \App\User::where('email', $httpRequest->username)->first();

            // Perform your validation here

            // If the validation is successfull:
            return $this->issueToken($request);
        
    

参考链接 - https://github.com/laravel/passport/issues/225#issuecomment-271057428

【讨论】:

我不确定你的代码是什么。 Laravel 护照随着时间的推移发生了变化,你现在可以覆盖这个方法 - github.com/laravel/passport/blob/5.0/src/Http/Controllers/… 这将返回错误“在文件中为 null 时调用成员函数 respondToAccessTokenRequest()”【参考方案3】:

您可以按照文档所述在您的用户模型中定义findForPassport 方法:

https://laravel.com/docs/5.8/passport#customizing-the-username-field

<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable

    use HasApiTokens, Notifiable;

    /**
     * Find the user instance for the given username.
     *
     * @param  string  $username
     * @return \App\User
     */
    public function findForPassport($username)
    
        return $this->where('username', $username)->first();
    

还有一个validateForPassportPasswordGrant 方法可以在用户模型中定义。它接收纯密码,因此您可以在此处进行任何其他验证。它需要一个布尔值,如果它通过验证,则为 true。

【讨论】:

以上是关于Laravel Passport:发送令牌请求时的附加模型条件的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 通过 Passport 实现 API 请求认证:令牌作用域详解

Laravel 通过 Passport 实现 API 请求认证:沙箱测试篇(私人访问令牌)

Laravel OAuth2 Passport API,生成令牌但无法发出请求:“未经身份验证”

Laravel 通过 Passport 实现 API 请求认证:开放平台篇(客户端凭证令牌)

Laravel 通过 Passport 实现 API 请求认证:移动端应用篇(密码授权令牌)

Laravel Passport:手动创建访问令牌