当前位置: 首页 > 知识库问答 >
问题:

Laravel的5.3护照和api路由

葛高澹
2023-03-14

我使用的是Laravel框架5.3版。9,通过composer全新下载未添加任何内容(除了“laravel/passport”:“^1.0”)。

我做了文件中建议的所有事情。创建了表,路由启动,一切正常。然而,我需要护照的API。

我的路线是这样的:

+--------+----------+-----------------------------------------+----------------------+----------------------------------------------------------------------------+------------+
| Domain | Method   | URI                                     | Name                 | Action                                                                     | Middleware |
+--------+----------+-----------------------------------------+----------------------+----------------------------------------------------------------------------+------------+
|        | GET|HEAD | /                                       |                      | Closure                                                                    | web        |
|        | GET|HEAD | api/v1/users/register                   | api::users::register | App\Http\Controllers\Api\V1\SocialController@register                      | api,auth   |
|        | POST     | oauth/authorize                         |                      | \Laravel\Passport\Http\Controllers\ApproveAuthorizationController@approve  | web,auth   |
|        | GET|HEAD | oauth/authorize                         |                      | \Laravel\Passport\Http\Controllers\AuthorizationController@authorize       | web,auth   |
|        | DELETE   | oauth/authorize                         |                      | \Laravel\Passport\Http\Controllers\DenyAuthorizationController@deny        | web,auth   |
|        | GET|HEAD | oauth/clients                           |                      | \Laravel\Passport\Http\Controllers\ClientController@forUser                | web,auth   |
|        | POST     | oauth/clients                           |                      | \Laravel\Passport\Http\Controllers\ClientController@store                  | web,auth   |
|        | PUT      | oauth/clients/{client_id}               |                      | \Laravel\Passport\Http\Controllers\ClientController@update                 | web,auth   |
|        | DELETE   | oauth/clients/{client_id}               |                      | \Laravel\Passport\Http\Controllers\ClientController@destroy                | web,auth   |
|        | GET|HEAD | oauth/personal-access-tokens            |                      | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@forUser   | web,auth   |
|        | POST     | oauth/personal-access-tokens            |                      | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@store     | web,auth   |
|        | DELETE   | oauth/personal-access-tokens/{token_id} |                      | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@destroy   | web,auth   |
|        | GET|HEAD | oauth/scopes                            |                      | \Laravel\Passport\Http\Controllers\ScopeController@all                     | web,auth   |
|        | POST     | oauth/token                             |                      | \Laravel\Passport\Http\Controllers\AccessTokenController@issueToken        |            |
|        | POST     | oauth/token/refresh                     |                      | \Laravel\Passport\Http\Controllers\TransientTokenController@refresh        | web,auth   |
|        | GET|HEAD | oauth/tokens                            |                      | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@forUser | web,auth   |
|        | DELETE   | oauth/tokens/{token_id}                 |                      | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@destroy | web,auth   |
+--------+----------+-----------------------------------------+----------------------+----------------------------------------------------------------------------+------------+

所有的web路由都在那里,没有api相关的路由,因为Passport不提供任何开箱即用的东西。

API本身旨在供可信客户端使用,它是为需要登录的移动应用程序而设计的。不过,所述登录将绕过几个步骤。

一旦用户访问了/注册路由,注册过程本身就很简单:访问用户的facebook帐户,抓取几个字段-电子邮件,facebook id,命名个人资料图片,从那时起,用户被认为是注册的。但是用户不会登录Facebook(这是一个非常重要的方面)。消费者应用将获得一个令牌,并使用该令牌访问api的各种endpoint(需要令牌才能使用)。

所以归结起来就是这样。我需要向访问API的消费者应用发布访问令牌。API本身只有一个客户端,即移动应用本身。使用应用的用户不被视为API的客户端,而是移动应用本身的客户端。

到目前为止,当涉及到实现API相关的东西时,Passport是一个让人头疼的问题,要么就是我不知道如何使它正常工作。

我在oauth\u clients表中创建了一个测试客户端,如下所示:

我使用Postman访问api/v1/用户/注册路由,该路由具有具有以下JSON应用程序/jsonauth中间件

{
    "grant_type" : "authorization_code",
    "client_id" : 5,
    "client_secet": "y5dvPIOxQJOjYn7w2zzg4c6TRrphsrNFWbG4gAUL"
}

这当然会导致

{"error":"Unauthenticated."}

这很有道理。出于好奇,我将/register路线改为:

Route::group([
    'middleware' => [
    ],
], function ()
{
    Route::group([
        'prefix' => 'users',
        'as'     => 'users::',
    ], function ()
    {
//        Route::get('/register', ['as'   => 'register', 'uses' => 'Api\V1\SocialController@register',]);
        Route::post('/register', ['as'   => 'register', 'uses' => '\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken',]);
    });

});

使用与之前相同的json。这导致{“error”:“invalid_client”,“message”:“client authentication failed”}

我已经找到了处理vendor/leagueoauth2server/src/Grant/AbstractGrant`中validateClient部分的函数。

$Client为空。现在,这可能与护照有关,也可能与护照无关,因为它的留档相当缺乏,一想到要通过一个包裹的怪物来追踪错误,这可能很大程度上是由于我没有做正确的事情,我就不觉得自己是一个好主意,我别无选择。老实说,我甚至不知道问题出在哪里。

实际上,在这一点上,任何指向正确方向的方式都是非常受欢迎的。

问题的部分是

共有2个答案

陆才俊
2023-03-14

由于标记的答案被认为是正确的,我认为有必要指出一些我认为许多人会同意的关键点:

>

在尝试“黑客式”完成一项可能已经完成多次的任务之前,请始终尝试利用并尽可能多地利用框架的功能。

确保你正在对已经完成的事情进行适当的研究。通过这种方式,只需参考视频或教程就可以更轻松地演示如何正确地完成某人正在尝试做的事情。

话虽如此,一个好的起点是观看下面的视频,它完美地描述了如何正确设置你想要设置的东西的基础知识:

https://laracasts.com/series/whats-new-in-laravel-5-3/episodes/13

在许多方面,视频教程做得非常好,从头到尾都很彻底。一定要温习一下OAuth2.0的不同Grant_Types,这样你就会更好地了解你/你的应用程序需要什么特定类型,这取决于你的应用程序使用api的位置:

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

此外,在创建或登录用户时,请确保使用laravel的开箱即用功能进行登录和注册。当您在控制台中执行以下操作时,将为您构建控制器:

php artisan make:auth

除此之外,如果护照是一个什么样的谜,你可以随时拉在拉拉威尔/社交名流包(https://github.com/laravel/socialite)。它将允许您“使用(此处的社交网络)登录”。前提是这也是你的目标路线。

结束语:我在你的问题中看到的最突出的部分是一个人如何注册但不登录facebook。相反,它将有一个访问令牌来访问各种APIendpoint。因此,如果我没有弄错你说的话,你的目标是在返回数据时使用facebook上的用户数据,该用户被视为已登录,并将获得访问令牌。因此:

>

当请求返回时,在主体中包含用户数据,运行检查以确保有数据(简单的if语句应该可以)。因为facebook已经对该用户进行了身份验证,并且发送了凭据,所以您应该可以开始了。

您可以在登录控制器中启动内部代理(这是一种更干净、更安全的方式),也可以发布JWT(在上面的回答中发布的视频的最后5分钟中介绍了这一点)。

下面是一些示例代码,让您开始学习。

App\Http\Controllers\Auth\LoginController。php

class LoginController extends Controller
{

    // ...

    protected function authenticateClient(Request $request) {

        $credentials = $this->credentials($request);

        $data = $request->all();

        $user = User::where('email', $credentials['email'])->first();

        $request->request->add([
            'grant_type'    => $data['grant_type'],
            'client_id'     => $data['client_id'],
            'client_secret' => $data['client_secret'],
            'username'      => $credentials['email'],
            'password'      => $credentials['password'],
            'scope'         => null,
        ]);

        $proxy = Request::create(
            'oauth/token',
            'POST'
        );

        return Route::dispatch($proxy);
    }

    protected function authenticated(Request $request, $user) {

        return $this->authenticateClient($request);
    }

    protected function sendLoginResponse(Request $request)
    {
        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        return $this->authenticated($request, $this->guard()->user());

    }

    public function login(Request $request)
    {

        if ($this->guard('api')->attempt($credentials, $request->has('remember'))) {

            return $this->sendLoginResponse($request);
        }
    }
}

如果您打算使用密码授权类型通过passport对客户端进行身份验证,则使用上述代码。然而,我会认真地看教程视频,然后再对任何事情大发雷霆。它将帮助您了解如何将laravel 5.3与passport一起使用。

薛弘厚
2023-03-14

Laravel 5.3护照的问题是,不同于以前的OAuth 2.0服务器Laravel库所提供的Lucadegasperi,它没有API直接使客户端。所以好像现在客户端只能通过前端来做。仅供参考,我们想仅为我们的移动应用程序使用laravel护照,所以在创建和注册用户时,我们只有电子邮件

注意:在执行以下操作之前,假定您已在应用程序中启用密码授予。

因此,我们在laravel 5.3上解决该问题的方法如下:

>

  • 在oauth_中,客户端将id字段转换为普通字段,即将其作为主键删除,并将数据类型设置为varchar,这样我们就可以将电子邮件地址存储为客户端id,因为它们对于您的系统也是唯一的。在Facebook登录的情况下,我们将Facebook用户ID存储在本栏中,这对于我们的每个客户来说都是唯一的。也适用于其他表,如:oauth_访问_令牌、oauth_验证_代码

    现在转到您的模型,并为oauth_clients表创建一个模型,这样您就可以在创建用户时通过代码以编程方式创建客户端。

    <?php
    namespace App;
    
    
    use Illuminate\Database\Eloquent\Model;
    
    class OauthClient extends Model
    {
        protected $table = 'oauth_clients';
    }
    

    然后在你的api中。php路由文件添加以下路由:

    Route::post('/register-user', function (Request $request) {
    
        $name     = $request->input('name');
        $email    = $request->input('email'),
        $password = $request->input('password'),    
    
        // save new user
        $user = \App\User::create([
          'name'     => $name,
          'email'    => $email,
          'password' => bcrypt($password),
        ]);
    
    
        // create oauth client
        $oauth_client = \App\OauthClient::create([
            'user_id'                => $user->id,
            'id'                     => $email,
            'name'                   => $name,
            'secret'                 => base64_encode(hash_hmac('sha256',$password, 'secret', true)),
            'password_client'        => 1,
            'personal_access_client' => 0,
            'redirect'               => '',
            'revoked'                => 0,
        ]);
    
    
        return [
            'message' => 'user successfully created.'
        ];
    });
    

    在上面的代码片段中,您必须注意到,要生成oauth_client秘密,您必须使用一些您觉得适合在应用程序中使用的强加密公式。此外,使用相同的技术在移动应用上为相应的客户端/用户生成密钥。

    现在,您可以使用laravel passport提供的标准POST API,通过使用“oauth/token”的密码授权,使用以下参数请求访问令牌:

    grant_type : 'password'
    client_id  : '<email with which the user is registered>'
    client_secret : '<generate the client secret from the mobile app>'
    username : '<email with which the user is registered>'
    password : '<password entered by the user>'
    scope : '<leave empty as default>'
    

    上面会给你一个回应,如果一切正确,类似于:

    {
      "token_type": "Bearer",
      "expires_in": 3155673600,
      "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3In0.eyJhdWQiOiJzaHVqYWhtQGdtYWlsLmNvbSIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3IiwiaWF0IjoxNDc4MTQ1NjMyLCJuYmYiOjE0NzgxNDU2MzIsImV4cCI6NDYzMzgxOTIzMiwic3ViIjoiMSIsInNjb3BlcyI6W119.dj3g9b2AdPCK-im5uab-01SP71S7AR96R0FQTKKoaZV7M5ID1pSXDlmZw96o5Bd_Xsy0nUqFsPNRQsLvYaOuHZsP8v9mOVirBXLIBvPcBc6lDRdNXvRidNqeh4JHhJu9a5VzNlJPm3joBYSco4wYzNHs2BPSxXuuD3o63nKRHhuUHB-HwjVxj2GDwzEYXdZmf2ZXOGRJ99DlWGDvWx8xQgMQtd1E9Xk_Rs6Iu8tycjBpKBaC24AKxMI6T8DpelnFmUbMcz-pRsgCWCF_hxv6FpXav3jr1CLhhT58_udBvXjQAXEbtHeB7W_oaMcaqezHdAeOWDcnqREZHsnXHtKt0JpymcTWBkS2cg7sJzy6P9mOGgQ8B4gb8wt44_kHTeWnokk4yPFRZojkHLVZb8YL6hZxLlzgV1jCHUxXoHNe1VKlHArdlV8LAts9pqARZkyBRfwQ8oiTL-2m16FQ_qGg-9vI0Suv7d6_W126afI3LxqDBi8AyqpQzZX1FWmuJLV0QiNM0nzTyokzz7w1ilJP2PxIeUzMRlVaJyA395zq2HjbFEenCkd7bAmTGrgEkyWM6XEq1P7qIC_Ne_pLNAV6DLXUpg9bUWEHhHPXIDYKHS-c3N9fPDt8UVvGI8n0rPMieTN92NsYZ_6OqLNpcm6TrhMNZ9eg5EC0IPySrrv62jE",
      "refresh_token": "BbwRuDnVfm7tRQk7qSYByFbQKK+shYPDinYA9+q5c/ovIE1xETyWitvq6PU8AHnI5FWb06Nl2BVoBwCHCUmFaeRXQQgYY/i5vIDEQ/TJYFLVPRHDc7CKILF0kMakWKDk7wJdl5J6k5mN38th4pAAZOubiRoZ+2npLC7OSZd5Mq8LCBayzqtyy/QA5MY9ywCgb1PErzrGQhzB3mNhKj7U51ZnYT3nS5nCH7iJkCjaKvd/Hwsx2M6pXnpY45xlDVeTOjZxxaOF/e0+VT2FP2+TZMDRfrSMLBEkpbyX0M/VxunriRJPXTUvl3PW0sVOEa3J7+fbce0XWAKz7PNs3+hcdzD2Av2VHYF7/bJwcDCO77ky0G4JlHjqC0HnnGP2UWI5qR+tCSBga7+M1P3ESjcTCV6G6H+7f8SOSv9FECcJ8J5WUrU+EHrZ95bDtPc9scE4P3OEQaYchlC9GHk2ZoGo5oMJI6YACuRfbGQJNBjdjxvLIrAMrB6DNGDMbH6UZodkpZgQjGVuoCWgFEfLqegHbp34CjwL5ZFJGohV+E87KxedXE6aEseywyjmGLGZwAekjsjNwuxqD2QMb05sg9VkiUPMsvn45K9iCLS5clEKOTwkd+JuWw2IU80pA24aXN64RvOJX5VKMN6CPluJVLdjHeFL55SB7nlDjp15WhoMU1A="
    }
    

    这只是一个临时的解决方案,直到laravel支持应用程序的外部API,只有一个移动作为创建oAuth客户端和用户的唯一可能接口。

    希望对你有帮助!干杯。

  •  类似资料:
    • 早些时候,当我使用Laravel5.2时,我使用了第三方软件包https://github.com/tymondesigns/jwt-auth/用于进行基于JWT的身份验证。我们只需要传递用户名和密码就可以获得令牌。 现在在laravel 5.3中,随着passport的引入,我想进行基于JWT的身份验证,但passport要求我指定客户端id和客户端密码以及用户名和密码。这在tymondesig

    • 我正在开发标准的LaravelRESTAPI。我正在关注Laravel5.4API认证(Passport)文档。 我需要的是,用户应该通过API登录并获得不会过期的访问令牌。 表具有列。默认值为一年。我把expires_at日期改成了昨天。但它仍然有效。我搜索关于Laravel Passport令牌寿命。有人说过期日期没有根据任何要求进行检查。 是真的吗?如果是真的,那么列的目的是什么?有人能解释

    • 最近我开始使用Laravel5.3来写博客,但是在运行

    • 我试图做api-auth通过检查生成令牌从登录用户的用户名与md5加密方法在laravel 5.5飞,不想保存令牌到用户的表。当用户注销时,令牌将无效。URL将是这样的: http://myserver.com/products?token=...... 我该怎么做? 新增-这是第44届世界技能大赛的测试项目,以下为测试项目文件: 认证 A.登录(v1/auth/登录) 描述:供客户端通过用户名和

    • 我使用任何类型的路由,然后在这个方法中,我在请求类型的基础上生成树。 路线 从控制器在检查类型之前我这样检查它

    • 我正在使用Laravel passport进行API身份验证,当我将其与一个DB一起使用时,它可以完美地工作,但当使用多个数据库时,它会给出, 我正在做的事情: > 我有一个多租户数据库,主数据库有用户、角色和所有OAuth表。 当我创建一个具有管理员角色的用户时,它将创建具有管理员名称的新数据库,它将创建包含用户、角色和所有OAuth表的子数据库。的子数据库将从主数据库复制密码授予令牌和个人访问