在本文中,我们将探讨如何使用Laravel Passport库在Laravel中设置成熟的OAuth2服务器。 我们将通过必要的服务器配置以及一个实际示例来演示如何使用OAuth2 API。
我假设您熟悉基本的OAuth2概念和流程,因为我们将在Laravel上下文中进行讨论。 实际上,Laravel Passport库使在应用程序中快速设置OAuth2服务器变得非常容易。 因此,其他第三方应用程序可以使用您的应用程序提供的API。
在本文的上半部分,我们将安装和配置必要的库,而下半部分将介绍如何在应用程序中设置演示资源以及如何从第三方应用程序中使用它们。
服务器配置
在本节中,我们将安装使Passport库与Laravel一起使用所需的依赖项。 安装后,我们需要进行很多配置,以便Laravel可以检测Passport库。
让我们继续使用composer安装Passport库。
$composer require laravel/passport
就Passport库安装而言,仅此而已。 现在,让我们确保Laravel知道这一点。
与Laravel一起使用时,您可能知道服务提供者的概念,该概念允许您在应用程序中配置服务。 因此,每当您想在Laravel应用程序中启用新服务时,只需在config/app.php
添加相关的服务提供者条目。
如果您还不了解Laravel服务提供者,我强烈建议您帮个忙,并阅读这篇介绍性文章 ,其中介绍了Laravel服务提供者的基础。
在我们的例子中,我们只需要将PassportServiceProvider
提供程序添加到config/app.php
中的服务提供程序列表config/app.php
,如以下代码片段所示。
...
...
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
Laravel\Tinker\TinkerServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
Laravel\Passport\PassportServiceProvider::class,
],
...
...
接下来,我们需要运行migrate
artisan命令,该命令在数据库中为Passport库创建必要的表。
$php artisan migrate
确切地说,它创建数据库中的表。
oauth_access_tokens
oauth_auth_codes
oauth_clients
oauth_personal_access_clients
oauth_refresh_tokens
接下来,我们需要生成一对公钥和私钥,Passport库将使用它们来进行加密。 正如预期的那样,Passport库提供了一个手Craft.io命令来轻松创建它。
$php artisan passport:install
那应该已经在storage/oauth-public.key
和storage/oauth-private.key
创建了密钥。 它还创建了一些演示客户端凭据,稍后我们将再使用。
接下来 ,让我们对Laravel用于身份验证的现有User模型类进行身份验证。 为此,我们需要将HasApiTokens
特性添加到User
模型类。 让我们按照以下代码片段所示进行操作。
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
HasApiTokens
特征包含帮助程序方法,这些方法用于验证请求中的令牌并在当前经过身份验证的用户的上下文中检查所请求资源的范围。
此外,我们需要在Laravel应用程序中注册Passport库提供的路由。 这些路由将用于标准OAuth2操作,例如授权,请求访问令牌等。
在app/Providers/AuthServiceProvider.php
文件的启动方法中,让我们注册Passport库的路由。
...
...
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
...
...
最后但并非最不重要的一点是,我们需要将config/auth.php
文件中的api
驱动程序从令牌更改为通行证,因为我们将使用Passport库进行API身份验证。
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
到目前为止,就OAuth2服务器配置而言,我们已经完成了所有必需的工作。
设置演示资源
在上一节中,我们进行了所有艰苦的工作来在应用程序中设置OAuth2身份验证服务器。 在本节中,我们将设置一个可以通过API调用请求的演示资源。
我们将努力使事情变得简单。 我们的演示资源返回用户信息,前提是GET
请求中存在有效的uid
参数。
让我们创建一个具有以下内容的控制器文件app/Http/Controllers/UserController.php
。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\User;
class UserController extends Controller
{
public function get(Request $request)
{
$user_id = $request->get("uid", 0);
$user = User::find($user_id);
return $user;
}
}
与往常一样,您还需要添加一个关联的路由,应该将其添加到routes/web.php
文件中。 但是我们在说的是API路由,因此需要特殊对待。
API路由在routes/api.php
文件中定义。 因此,让我们继续添加我们的自定义API路由,如以下代码片段所示。
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
// custom API route
Route::middleware('auth:api')->get('/user/get', 'UserController@get');
尽管我们将其定义为/user/get
,但有效的API路由是/api/user/get
,这是在该路由上请求资源时应该使用的路由。 api
前缀由Laravel自动处理,您不必为此担心!
在下一节和最后一节中,我们将讨论如何创建客户端凭据并使用OAuth2 API。
如何使用OAuth2 API
现在,我们已经在应用程序中设置了OAuth2服务器,任何第三方都可以使用OAuth连接到我们的服务器并使用我们应用程序中可用的API。
首先,第三方应用程序必须在我们的应用程序中注册才能使用API。 换句话说,它们被视为客户端应用程序,它们将在注册时收到客户端ID和客户端密码。
Passport库提供了一个熟练的命令,可以轻松创建客户帐户。 让我们继续创建一个模拟客户帐户。
$php artisan passport:client
Which user ID should the client be assigned to?:
> 1
What should we name the client?:
> Demo OAuth2 Client Account
Where should we redirect the request after authorization? [https://localhost/auth/callback]:
> http://localhost/oauth2_client/callback.php
New client created successfully.
Client ID: 1
Client secret: zMm0tQ9Cp7LbjK3QTgPy1pssoT1X0u7sg0YWUW01
当您运行artisan passport:client
命令时,它会在创建客户帐户之前询问您几个问题。 其中,有一个重要的问题要求您提供callback URL
。
callback URL
是授权后将用户重定向到第三方的callback URL
。 这就是应该用于交换访问令牌的授权代码的发送位置。 我们将在稍后创建该文件。
现在,我们准备在Laravel应用程序中测试OAuth2 API。
为了演示起见,我将oauth2_client
在文档根目录下创建oauth2_client
目录。 理想情况下,这些文件将位于要使用Laravel应用程序中的API的第三方端。
让我们使用以下内容创建oauth2_client/auth_redirection.php
文件。
<?php
$query = http_build_query(array(
'client_id' => '1',
'redirect_uri' => 'http://localhost/oauth2_client/callback.php',
'response_type' => 'code',
'scope' => '',
));
header('Location: http://your-laravel-site-url/oauth/authorize?'.$query);
确保更改client_id
和redirect_uri
参数以反映您自己的设置,即您在创建演示客户帐户时使用的设置。
接下来,让我们使用以下内容创建oauth2_client/callback.php
文件。
<?php
// check if the response includes authorization_code
if (isset($_REQUEST['code']) && $_REQUEST['code'])
{
$ch = curl_init();
$url = 'http://your-laravel-site-url/oauth/token';
$params = array(
'grant_type' => 'authorization_code',
'client_id' => '1',
'client_secret' => 'zMm0tQ9Cp7LbjK3QTgPy1pssoT1X0u7sg0YWUW01',
'redirect_uri' => 'http://localhost/oauth2_client/callback.php',
'code' => $_REQUEST['code']
);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$params_string = '';
if (is_array($params) && count($params))
{
foreach($params as $key=>$value) {
$params_string .= $key.'='.$value.'&';
}
rtrim($params_string, '&');
curl_setopt($ch,CURLOPT_POST, count($params));
curl_setopt($ch,CURLOPT_POSTFIELDS, $params_string);
}
$result = curl_exec($ch);
curl_close($ch);
$response = json_decode($result);
// check if the response includes access_token
if (isset($response->access_token) && $response->access_token)
{
// you would like to store the access_token in the session though...
$access_token = $response->access_token;
// use above token to make further api calls in this session or until the access token expires
$ch = curl_init();
$url = 'http://your-laravel-site-url/api/user/get';
$header = array(
'Authorization: Bearer '. $access_token
);
$query = http_build_query(array('uid' => '1'));
curl_setopt($ch,CURLOPT_URL, $url . '?' . $query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($ch);
curl_close($ch);
$response = json_decode($result);
var_dump($result);
}
else
{
// for some reason, the access_token was not available
// debugging goes here
}
}
同样,请确保根据上述文件中的设置调整URL和客户端凭据。
总共如何运作
在本节中,我们将从最终用户的角度进行全面测试。 作为最终用户,您面前有两个应用程序:
- 第一个是您已经拥有帐户的Laravel应用程序。 它包含您可以与其他第三方应用程序共享的信息。
- 第二个是演示的第三方客户端应用程序
auth_redirection.php
和callback.php
,它希望使用OAuth API从Laravel应用程序中获取您的信息。
该流程从第三方客户端应用程序开始。 继续并在浏览器中打开http://localhost/oauth2_client/auth_redirection.php URL,这应该将您重定向到Laravel应用程序。 如果您尚未登录Laravel应用程序,则该应用程序将首先要求您登录。
用户登录后,应用程序将显示授权页面。
如果用户授权该请求,则该用户将被重定向回http://localhost/oauth2_client/callback.php上的第三方客户端应用程序,同时将code
以及包含授权代码的GET
参数作为代码。
第三方应用程序收到授权代码后,便可以与Laravel应用程序交换该代码以获取访问令牌。 这正是在oauth2_client/callback.php
文件的以下代码片段中oauth2_client/callback.php
。
$ch = curl_init();
$url = 'http://your-laravel-site-url/oauth/token';
$params = array(
'grant_type' => 'authorization_code',
'client_id' => '1',
'client_secret' => 'zMm0tQ9Cp7LbjK3QTgPy1pssoT1X0u7sg0YWUW01',
'redirect_uri' => 'http://localhost/oauth2_client/callback.php',
'code' => $_REQUEST['code']
);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$params_string = '';
if (is_array($params) && count($params))
{
foreach($params as $key=>$value) {
$params_string .= $key.'='.$value.'&';
}
rtrim($params_string, '&');
curl_setopt($ch,CURLOPT_POST, count($params));
curl_setopt($ch,CURLOPT_POSTFIELDS, $params_string);
}
$result = curl_exec($ch);
curl_close($ch);
$response = json_decode($result);
接下来,第三方应用程序检查CURL请求的响应,以首先查看它是否包含有效的访问令牌。
第三方应用程序一旦获得访问令牌,便可以使用该令牌进行进一步的API调用,以根据需要从Laravel应用程序请求资源。 当然,访问令牌需要在从Laravel应用程序请求资源的每个请求中传递。
我们试图模仿用例,因为第三方应用程序希望从Laravel应用程序访问用户信息。 并且我们已经在Laravel应用程序中构建了一个API端点http:// your-laravel-site-url / api / user / get来简化它。
// check if the response includes access_token
if (isset($response->access_token) && $response->access_token)
{
// you would like to store the access_token in the session though...
$access_token = $response->access_token;
// use above token to make further api calls in this session or until the access token expires
$ch = curl_init();
$url = 'http://your-laravel-site-url/api/user/get';
$header = array(
'Authorization: Bearer '. $access_token
);
$query = http_build_query(array('uid' => '1'));
curl_setopt($ch,CURLOPT_URL, $url . '?' . $query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($ch);
curl_close($ch);
$response = json_decode($result);
var_dump($result);
}
这就是您应该如何在Laravel中使用OAuth2 API的完整流程。
至此,我们到了本文的结尾。
结论
今天,我们探索了Laravel中的Passport库,该库使我们能够非常轻松地在应用程序中设置OAuth2服务器。
对于那些刚刚开始使用Laravel或希望通过扩展来扩展您的知识,网站或应用程序的人,我们可以在Envato Market中进行很多研究。
请使用以下供稿,随时分享您的想法和疑问!
翻译自: https://code.tutsplus.com/tutorials/setup-oauth2-server-using-passport-in-laravel--cms-30576