【问题标题】:How can I create a token for a Password Grant Client using Laravel Passport?如何使用 Laravel Passport 为密码授予客户端创建令牌?
【发布时间】:2017-12-14 03:00:16
【问题描述】:

我正在构建一个 API,并且我正在使用 Laravel Passport 进行身份验证。

该 API 用于我们的移动应用,因此我们使用 Password Grant Client。

一切都很好,用户可以登录以获得访问令牌。我们创建了一个注册端点,允许用户注册。此时我们也需要 API 返回访问令牌。

查看文档没有办法以编程方式创建访问令牌。

如何在我的控制器中为密码授予客户端创建访问令牌?我显然不想向我自己的 API 发出 HTTP 请求来获取它。

我知道我可以使用个人访问授权客户端并在用户模型上调用 createToken,但这意味着访问令牌与不同的客户端相关联。这对我来说似乎不对。

【问题讨论】:

  • 这确实是一个非常好的问题。我也面临同样的情况。

标签: php laravel oauth laravel-passport


【解决方案1】:

我知道我可以使用个人访问授权客户端并在用户模型上调用 createToken,但这意味着访问令牌与不同的客户端相关联

不知道你的意思,你能解释一下吗?

现在这并不理想,但您也许可以注入 \League\OAuth2\Server\Grant\PasswordGrant 并使用

respondToAccessTokenRequest(ServerRequestInterface $request 
                            ResponseTypeInterface $responseType,
                            \DateInterval $accessTokenTTL)

您必须构建所有这些对象,但这是唯一一个返回任何令牌信息的密码公共方法。

【讨论】:

    【解决方案2】:

    我已经玩了几个星期的 Passport,从我在文档中看到的内容来看,它并没有公开它用于创建令牌的许多方法。虽然您可能无法轻松地“在我的控制器中为密码授予客户端创建访问令牌” - 您可以做的是使用 Route::dispatch 将令牌请求转发到您的 Passport Password Grant 路由。

    要在您用于颁发令牌的控制器中执行此操作,请使用 AuthenticatesUsers 特征,以便您可以访问 Password Grant 路由、创建请求并将该请求分派到 Password Grant 路由:

    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use Illuminate\Support\Facades\Route;
    use Illuminate\Foundation\Auth\AuthenticatesUsers;
    
    class IssueTokensController extends Controller
    {
    
        use AuthenticatesUsers;
    
        protected function issueApiToken(Request $request)
        {
            // forward the request to the oauth token request endpoint
            $tokenRequest = Request::create(
                '/oauth/token',
                'post'
            );
            return Route::dispatch($tokenRequest);
        }
    
    }
    

    此方法当然需要您设置 Passport 和 Password Grant Client。

    此答案基于 Raymond Lagonda 对类似问题的另一个答案 - 请参阅 https://stackoverflow.com/a/40433000/4991377

    【讨论】:

      【解决方案3】:

      试试这样的

      class UserController extends Controller
      {
          protected function login(Request $request)
          {
      
               $request->request->add([
                  'grant_type'    => 'password',
                  'client_id'     => '3',
                  'client_secret' => '6BHCRpB4tpXnQvC1DmpT7CXCSz7ukdw7IeZofiKn',
                  'scope' => '*'
              ]);
      
              // forward the request to the oauth token request endpoint
              $tokenRequest = Request::create('/oauth/token','post');
              return Route::dispatch($tokenRequest);
          }
      
      }
      

      【讨论】:

      • 这种方式发出一个请求,也就是说如果你需要在另一个请求中生成一个token,你的响应时间会很长。
      【解决方案4】:

      Patrick 的想法是正确的,这就是我最终要做的事情: (我不认为Sanju的回答是对的,因为你需要发出http请求)

      <?php
      
      namespace MyApp\Http\Controllers\API;
      
      use Illuminate\Http\Request;
      use Laravel\Passport\Http\Controllers\ConvertsPsrResponses;
      use League\OAuth2\Server\AuthorizationServer;
      use MyApp\Http\Controllers\APIController;
      use Illuminate\Auth\AuthenticationException;
      use Zend\Diactoros\ServerRequest;
      use Zend\Diactoros\Response as Psr7Response;
      
      class LoginController extends APIController
      {
      
          use ConvertsPsrResponses;
      
          /**
           *
           * @param Request $request
           * @param AuthorizationServer $authServer
           * @return \Illuminate\Http\JsonResponse
           * @throws AuthenticationException
           * @throws \League\OAuth2\Server\Exception\OAuthServerException
           */
          public function login(Request $request, AuthorizationServer $authServer)
          {
              $token = $this->getPasswordToken($request, $authServer);
              $data = [
                  "token_details" => $token,
              ];
      
              return $this->successResponse(
                  'Successful Login',
                  200,
                  $data
              );
      
          }
      
      
          /**
           * @param $request
           * @param AuthorizationServer $authServer
           * @return mixed
           * @throws \League\OAuth2\Server\Exception\OAuthServerException
           */
          private function getPasswordToken($request, AuthorizationServer $authServer)
          {
              $parsedBody = [
                  'grant_type' => 'password',
                  'client_id' => config('app.client_id'),
                  'client_secret' => config('app.client_secret'),
                  'username' => $request->username,
                  'password' => $request->password,
                  'scope' => '',
              ];
      
              $serverRequest = new ServerRequest(
                  $request->server(),
                  [],
                  null,
                  $request->method(),
                  'php://input',
                  $request->header(),
                  [],
                  [],
                  $parsedBody
              );
      
              $response = $this->convertResponse(
                  $authServer->respondToAccessTokenRequest($serverRequest, new Psr7Response)
              );
              return json_decode($response->getContent());
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2018-02-01
        • 2018-11-23
        • 1970-01-01
        • 2019-02-20
        • 2023-03-27
        • 2017-10-05
        • 2017-04-10
        • 2021-04-07
        • 2018-03-23
        相关资源
        最近更新 更多