为啥客户凭证应该与 Laravel Passport 中的用户相关联?

Posted

技术标签:

【中文标题】为啥客户凭证应该与 Laravel Passport 中的用户相关联?【英文标题】:Why should Client Creadentials be associated with a user in Laravel Passport?为什么客户凭证应该与 Laravel Passport 中的用户相关联? 【发布时间】:2017-09-28 02:43:04 【问题描述】:

我想使用客户端凭据对客户端应用程序进行身份验证以访问 API。

我的问题是创建客户端凭据。使用 php artisan passport:client 需要我输入一个 user_id 以将客户端与该用户相关联。我不明白。为什么客户端应用程序必须与用户关联?!还是有别的办法?

passport:client 命令只支持创建密码授权客户端和个人授权客户端。我认为它们中的任何一个都不是我需要的。

我真正需要的是创建仅由客户端应用程序用来授权自己访问某些 API 的客户端凭据。该怎么做?

【问题讨论】:

【参考方案1】:

我假设您想使用机器对机器身份验证(无用户交互)

我建议您通读几遍文档以掌握其中的窍门。

我不相信有创建唯一客户端凭据客户端的特定方法,我所做的是创建一个个人客户端然后更改数据库中个人客户端的字段personal_access_client1 => 0

您可以使用个人客户端选项,如 --help 选项所示

Usage:
  passport:client [options]

Options:
      --personal        Create a personal access token client
      --password        Create a password grant client
      --name[=NAME]     The name of the client
  -h, --help            Display this help message
...

php artisan passport:client --personal

输出

Personal access client created successfully.
Client ID: 1
Client Secret: LbjQNxK5SQZ3pPrEBUwbkE8vaRkg8jh25Qh43HYy

您需要使用默认中间件以外的其他中间件,因为使用此方法时没有用户在场

在内核中定义客户端凭据别名中间件 向路由添加中间件 发送请求

为 http 内核定义客户端凭据中间件

\App\Http\Kernel:

 protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
        //ommited
    ];

在路由上定义中间件

Route::get('/test', 'ApiTestController@test')->middleware('client_credentials');

\App\Http\Controllers\ApiTestController:

public function test() 
        return response()->json(['data' => 'hey'] );

来自php artisan route:list

GET|HEAD  | api/test | App\Http\Controllers\ApiTestController@test   | api,client_credentials  |

发送请求

遵循客户端凭据授予令牌文档中的指定请求

为了简单起见,我使用 Postman,使用 Postman (www.getpostman.com) 轻松发送测试请求

将授权设置为 OAuth 2.0,图片:Postman authentication

将访问令牌 URL、客户端 ID、客户端密码和授权类型设置为“客户端凭据”,图片:Postman OAuth Fields

Postman 创建一个令牌并将其附加到 URL 或 Header,在本例中为 header

Accept:application/json
Authorization:Bearer eyJ0eXAiOi...KCjK0

回复:


  "data": "hey"

【讨论】:

好的,Laravel Passport 没有办法“创建唯一的客户端凭据客户端”。但是我期待它错了吗?我是否错过了“机器对机器通信不包括任何用户交互并且不模拟任何用户并且访问可能不受单个用户限制”的内容? 通过客户端凭据进行身份验证的客户端将充当服务帐户,不模拟用户,也不涉及用户模型。如果您查看 \Laravel\Passport\ClientRepository::create\Laravel\Passport\Console\ClientCommand::createPersonalClient 中的 create 命令,user_id 将保留为 null 并将 $personalAccess 设置为 true 您可以使用句柄方法中注入的 ClientRepository 依赖项来实现您自己的命令跨度> 以及如何测试它?我在测试客户端访问令牌时遇到问题,因为 Passport 作为助手需要用户对象。 @rslhdyt,这是我为测试所做的: * 在 setUp: * 创建一个客户端 assport::client()->fill([...]) * 向 /oauth/token 发出请求并将访问令牌存储在一个属性中 * 对于您要测试的每个请求,都需要一个 Authorization 标头,其中包含:Bearer access_token【参考方案2】:

这些答案有点老了。

您当然可以添加客户端凭据。

php artisan passport:client --client

protected $signature = 'passport:client
        --personal : Create a personal access token client
        --password : Create a password grant client
        --client : Create a client credentials grant client
        --name= : The name of the client
        --provider= : The name of the user provider
        --redirect_uri= : The URI to redirect to after authorization 
        --user_id= : The user ID the client should be assigned to 
        --public : Create a public client (Auth code grant type only) ';

【讨论】:

感谢您的回答。它为我提供了一个起点来进行搜索以解决我的具体问题。【参考方案3】:

我本来想发表评论,但我还没有足够的声誉=p

您可以为命令指定一个不需要任何用户输入的名称参数。至于如何在没有人工干预的情况下将客户机密传递给您的客户,这才是真正的魔法所在。

php artisan passport:client --personal --name=someName

该命令仍然会给你:


Personal access client created successfully.
Client ID: 1
Client Secret: LbjQNxK5SQZ3pPrEBUwbkE8vaRkg8jh25Qh43HYy

正如预期的那样。

【讨论】:

以上是关于为啥客户凭证应该与 Laravel Passport 中的用户相关联?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们必须在 OAuth 中“更改令牌凭证的临时凭证”?

为啥我不能查看这个 laravel 项目?

为啥 GuzzleHttp 客户端在 Laravel/Lumen 上使用它发出网络请求时会抛出 ClientException?

Android/IOS Secret 过期管理与客户端凭证流

为啥 laravel 广播频道有默认前缀?

SAP固定资产无收入报废(ABAVN),为啥产生的会计凭证没有将固定资产清理转入营业外支出?