「 原创 」Laravel 5.8 API 开发实战(四)

安装 Passport

用 composer 安装 passport,运行 composer require laravel/passport

「 原创 」Laravel 5.8 API 开发实战(四)

安装passport

安装完成后,passport 服务提供器会自动使用框架注册自己的数据库迁移目录,只需要运行 php artisan migrate 即可。

当然了,如果不想使用 passport 的默认迁移,可以在 AppServiceProvider 的 register 方法中调用忽略迁移的方法 Passport::ignoreMigrations

「 原创 」Laravel 5.8 API 开发实战(四)

注册数据表


生成密钥

运行 php artisan passport:install,该命令会生成安全访问令牌时所需要的加密密钥

「 原创 」Laravel 5.8 API 开发实战(四)

生成密钥


更新模型

上述命令执行完成,生成密钥后,需要将 Trait 添加到 APP/User 模型中,提供一些需要的辅助函数。

<code> 'datetime',
    ];
    
    /**
     * 通过用户名/手机号码找到对应的用户信息
     *
     * @param string $username
     * @return User
     */
    public function findForPassport($username) {
        return $this->orWhere('username', $username)->orWhere('email', $username)->orWhere('phone', $username)->first();
    }
}/<code>


服务提供器(Provider)

在 app/Providers 目录下,修改 AuthServiceProviders.php 中的 boot 方法,调用 Passport::routes 函数,这个函数会注册一些必须的路由(发出 / 撤销 访问令牌(客户端 / 个人)等)

<code> 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}/<code>


授权看守器(Guard)

修改配置文件 config/auth.php 中 api 的授权看守器 gurads,将 driver 选项改为 passport。

<code>'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
]/<code>


token 有效期

Passport 颁发的访问令牌,默认是一年有效的,如果想自定义访问令牌的有效期,可使用 tokensExpireIn 及 refreshTokensExpireIn 方法去设置(app/Providers/AuthServiceProvider.php)

<code>public function boot() {
    $this->registerPolicies();
    Passport::routes();
    Passport::tokensExpireIn(now()->addDays(10));
    Passport::refreshTokensExpireIn(now()->addDays(30));
}/<code>


部署 passport

运行:php artisan passport:keys (该命令会生成 Passport 生成访问令牌所需的密钥)

「 原创 」Laravel 5.8 API 开发实战(四)



密码授权令牌

OAuth2 密码授权机制,可以非常方便自己的客户端通过手机号码(或邮箱)+ 密码的形式,进行授权,获取访问令牌,无需遍历整个OAuth2 整个授权流程。

密码授权客户端

如果此前安装 passport 时,执行过 php artisan passport:install 命令的,将无需执行下面的命令,因为该指令已经生产两条数据,即生成了对应的客户端,具体可以查看 oauth_client 数据表。

若是未执行上述命令,可执行:php artisan passport:client --password ,对应的输入想要的用户名即可。

「 原创 」Laravel 5.8 API 开发实战(四)

「 原创 」Laravel 5.8 API 开发实战(四)

生成密码授权客户端


请求令牌

客户端创建后,就可以通过电子邮件地址与密码向 /oauth/token 发 POST 请求了,需要注意的是,该路由已经通过 Passport::routes 注册过,无需另外手动注册,如果请求成功,则会返回如下所示的 JSON 对象,包含 token_type(类型),expires_in(过期时间),access_token 及 refresh_token

<code>{
    "token_type": "Bearer",
    "expires_in": 1296000,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjQxOTI0MWIyMTYyMDkwMGEzMjBhZjVjZWUxNjgzYzkwZTE2Y2NiOTcyMzE3MzU4NzRiNmNkNTgxNTZjNzY3YzhlNjJiMjNlNWJkYzdjZDM1In0.eyJhdWQiOiI0IiwianRpIjoiNDE5MjQxYjIxNjIwOTAwYTMyMGFmNWNlZTE2ODNjOTBlMTZjY2I5NzIzMTczNTg3NGI2Y2Q1ODE1NmM3NjdjOGU2MmIyM2U1YmRjN2NkMzUiLCJpYXQiOjE1NTY1Mjk4NjUsIm5iZiI6MTU1NjUyOTg2NSwiZXhwIjoxNTU3ODI1ODY1LCJzdWIiOiIxIiwic2NvcGVzIjpbIioiXX0.ng5lmGdiwRGOxYRkW7R0Ox7VSb5pWIlRaxMbWikbIP0GyEhL4ABJjvA4LVNb8k0molnghbTrUxr8V9yNTI-dVzt8iNzEXEvQ2N_jBWL-96M85V_QybDq0nHMU5vdPqxbbcjZNoAz53GD-QQPpwlaT6X1IpjjkAcXKwY_SBywGG3LSeaYEVO9GhcSjEG27BDFdYHHWD6C-gJwt1IsZ5ggfgxsC3vakfay3aQbRaoQycvk_lYzJA-xwcqJodOx6OkeSPm64Whq2njbyQ4YRUsvLo6DbWm5bZ6vVd4INTetwJErjMMn6XMcHp3Oont6UetuMeg_VdhPcnI58ew1DjbDAlpBk-B5z-MAMxPrhQYLFgsqOU8YdSQD4ddTD7OW9NUyjvNqcQAvoJIYfUCsGw3hTG9VXG7TyJQJQ_I5oq7_5gHLcuaHJn5Pzfq47Tql88UnoQZKSw4FcfEDP7uXNXAdg5edc4wnog8LMeIa6WqYXfnjy5rIjLnhJcq-6Ot4KIOVjNL3teDLCe9A7fv7tdLSJiCf4Pz-jEjRS_Z0pdHdwyFihUWcl578JKHAHlj4B0CY9zXSmTdNeY-LofKP1vaFX8Ct6sQsYOJB-O3oOqfxeVHNRYD6liPWnLcFmyBFR9qV-XpSCR-PnxwBUJ9s0v_tCpHfwDMO6T8jf72OxZ-H8IA",
    "refresh_token": "def502005aa00689b542002eb9f23e83351ffeb309d6b804023b533804d36652ad1a8458fe7bf14e25043b28c2b842938dd6b056202bddd568d6bdccdd000d913c76cfd281b7a1df56675c4f04f56f4b63b68011d13a5e363bf64de44931faabf22b672f63cbe215f664f52c1830d217f39c3688adaec49f97f95652777e9f4bab5184c6d51c0ae93ad0f3b64c01c0b22bc67c577c6fa9a4247a8865a6eae9b3f37d1c496e9274e4ae6bb01e830461bde27e562f3a31f420bd34cb1d30456336c85cc40dcf8290b74d7661ade84efe81cfa3fc623c78bb3f6ca385dcc60278e6be10c9127206ca55144f7d419e87b89e19d48e159b790d66d3d65860dacc87f7b9806e770eff8436c87c18cdfa75a2e4e7cc1430876b78f647608189214fc2daa465758e6c51909a08bd1aa868978821144b74f65a124d84195d1b0cbafdbca9c664ac082b1f2bd14aa728d740a7b17073413db6af179940d79de0b43ada6f01ee56795a"
}/<code>
「 原创 」Laravel 5.8 API 开发实战(四)

POST请求成功后的返回

请求令牌过程中有几个需要注意的点:

1 - 采用 postman 之类的工具请求时,用 application/x-www-form-urlencode,即 form data 形式提交,否则会返回 unsupported_grant_type 的错误。

2 - 如果出现 invalid_credentials 错误,修改提交参数,默认未修改的情况下,username 值使用电子邮件地址,即类似以 [email protected] 作为 username 的值 ( 当然,可以自定义用户名字段, 查看上面所述中《更新模型》这一块的内容 )

3 - 该方式,默认情况下,发放的访问令牌是长期有效的,如果需要修正时间,请查看 《Laravel 5.8 API 开发实战(三)》

「 原创 」Laravel 5.8 API 开发实战(四)

unsupported_grant_type 错误

「 原创 」Laravel 5.8 API 开发实战(四)

invalid_credentials 错误


请求作用域

使用密码授权机制时,请求参数中若携带了 scope 参数,且值为 * 的话,令牌实例中的 can 方法将一直都返回 true 的状态;这种作用域的授权只能分配给使用 password 授权的令牌。

颁发访问令牌

使用授权码时,客户端的应用程序会将用户重定向我们的授权服务器,授权服务器返回信息进行询问用户,是批准还是拒绝该客户端访问授权令牌(如果对于OAuth的授权流程不清楚的话,可以查看阮一峰《关于 OAuth2.0 的理解》的日志)

管理客户端

很显然,为了方便测试 OAuth2.0 的功能,我们需要生成一个 [ 客户端 ] 来注册自己的应用程序,完成整个授权流程, php artisan passport:client,该命令会创建一个客户端(第三方或用户是无法使用 client 命令的,此处是为了方便测试)。

「 原创 」Laravel 5.8 API 开发实战(四)

如上图所示,为这个客户端分配了 user 表中 id = 1 的用户;若该 user 表为空的话,可以运行如下命令完成用户创建。

<code>php artisan tinker
App\User::create(['name' => 'makeit', 'email' => '[email protected]', 'password' => bcrypt('123456')]);/<code> 
「 原创 」Laravel 5.8 API 开发实战(四)

虽然用户或者第三方无法使用 client 命令进行客户端创建,但是 Laravel 提供了一系列的接口,我们也就不用费时费事的去编写控制器来操作了,当然,要管理这些客户端,还是需要添加,删除等相关的管理页面的;此处我们为了方便测试,就不进行页面展示了,我们只用 postman,resetlet 等工具来进行接口测试,但是这些 API 由 web 与 auth 两个中间件的保护,正常情况下只能从应用程序内部进行调用,外部是不允许调用的,所以需要进行一些准备工作的,本篇就说一下跨域问题的解决,其它的准备工作就先不赘述了。

CORS 跨域

composer require barryvdh/laravel-cors,执行该命令,安装 laravel-cors

「 原创 」Laravel 5.8 API 开发实战(四)

安装 laravel-cors


config/app.php 文件内的 alials 中,添加如下内容,注册相应的服务:

<code>'CROS' => Barryvdh\Cors\HandleCors::class/<code>

修改 app/Http/Kernel.php 文件,此处可分全局和局部使用两种方式,全局使用则将该服务添加到 $middleware 内容中,局部的则添加至 $middlewareGroups 中的 web / api 中都可以。

<code>/<code>
「 原创 」Laravel 5.8 API 开发实战(四)

全局使用

「 原创 」Laravel 5.8 API 开发实战(四)

局部使用

执行 php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider" 发布 cors 的配置。

「 原创 」Laravel 5.8 API 开发实战(四)

发布配置后,在 config 目录下生成了 cors.php 配置文件,可以在 allowedHeaders 自定义 header,比如 Content-Type,X-Requested-With。白名单或者确定可访问的域名,在 allowedOrigins 添加即可,自行配置。

「 原创 」Laravel 5.8 API 开发实战(四)

至此,oAuth 2.0 密码授权令牌的实现就完成了,另外还讲述了相关的客户端管理及其跨域的一些问题,三四篇下来,基本上 API 开发的起步工作算是完成了,从最初《Laravel 5.8 API 开发实战(一)》跑通无授权的接口,至《Laravel 5.8 API 开发实战(二)》实现 jwt-auth 的认证,再到《Laravel 5.8 API 开发实战(三)》实现无感刷新 token,再到当前实现 oAuth 2.0 密码授权,总结整理了 API 开发的前期准备工作,后续将结合开发实际,说说具体的功能点,比如采用 RabbitMQ,结合 QQ 邮箱,实现注册的邮件的异步发送,加快响应速度之类的 ......


分享到:


相關文章: