سرفصل‌های آموزشی
آموزش OAuth و Laravel Passport
راه اندازی سرور OAuth با استفاده از Passport

راه اندازی سرور OAuth با استفاده از Passport

در بخش قبل، پروژه ی کاربردی که مثال پایه برای آموزش پاسپورت هست را به خوبی راه اندازی کردیم. در این بخش می‌خواهیم مراحل نصب و راه اندازی سرور OAuth را بر روی این مثال پایه پیش ببریم.

 

نصب و راه‌اندازی پاسپورت


برای استفاده از پکیج پاسپورت، نیاز است آن را با استفاده از Composer نصب کنیم پس به مسیر روت پروژه رفته و دستور زیر را وارد ‌کنیم. با استفاده از این دستور، پکیجLaravel Passport  نصب و به برنامه ی ما اضافه می‌شود. (به دلیل این که در پروژه ی کاربردی لاراول 7 نصب شده است مجبوریم از نسخه ی 9 پاسپورت استفاده کنیم)

composer require laravel/passport:^9.*

سپس باید با استفاد از دستور migrate، تمام جداول پایگاه داده مورد نیاز پاسپورت را ایجاد کنیم. با اجرای دستور زیر، جداول مورد نیاز برنامه برای ذخیره‌سازی کلاینت‌ها و access token ها ایجاد می‌شود. همان‌طور که در شکل دیده می‌شود تعدادی جدول با پیشوند oauth وجود دارد که مربوط به پاسپورت می‌باشد. 

php artisan migrate

در مرحله بعد، باید دستوری را اجرا کنیم که به پاسپورت اجازه می‌دهد کلید های رمزگذاری مورد نیاز برای تولید access token را به صورت ایمن ایجاد کند. همچنین این دستور، یک دسترسی شخصی یا “personal access” و یک اعطای مجوز یا “password grant” را ایجاد می‌کند که برای تولید access token استفاده می‌شود. در ادامه دوره درباره personal access و password grant توضیح داده خواهد شد.

php artisan passport:install

بعد از اجرای دستور بالا، خروجی نشان داده شده مانند شکل زیر می‌باشد:

اگر به جدول oauth_clients در بانک اطلاعاتی خود نگاه کنید، 2 رکورد با id های 1 و 2 و secret های مشخص شده در شکل بالا را می بینید.

انجام تنظیمات پاسپورت

بعد از نصب پاسپورت نیاز است یک سری تنظیمات را انجام دهیم تا بتوانیم از آن استفاده کنیم.

1-     ابتدا باید یک trait با نام HasApiTokens را به مدل User اضافه کنیم. این trait، چندین متد را برای مدل User فراهم می‌کند که با استفاده از آن‌ها می‌توانیم scope‌ها و token مربوط به کاربر را بررسی کنیم.

 

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
// …

2-     در مرحله بعد، فایل AuthServiceProvider در مسیر app/Providers را باز کنید و در متد boot آن، متد Passport::routes را فراخوانی کنید. این متد مسیرهای لازم برای صدور access token ها، باطل کردن access token ها، کلاینت‌ها و access token های شخصی را ثبت خواهد کرد. توجه داشته باشید که برای import کردن پکیج پاسپورت لاراول، نیاز است که این خط را اضافه کنید.

<?php

namespace App\Providers;

// …

use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    // …

    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}

// …

3-     سپس فایل config/auth.php را باز کرده و  به بخش guards بروید و مقدار کلید driver از بخش api  را برابر با passport قرار دهید. این تنظیم به برنامه شما دستور می‌دهد تا هنگام تایید اعتبار درخواست‌هایAPI ، از Passport TokenGuard  استفاده کند:

'guards' => [
    // …

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

ایجاد رابط کاربری برای مدیریت کلاینت ها و توکن های OAuth

در این بخش می‌خواهیم امکاناتی که پاسپورت در اختیار ما قرار می‌دهد را فعال کنیم. یکی از آن‌ها رابط کاربری است که در آن کاربران می‌توانند کار‌هایی مانند مدیریت برنامه‌های کلاینت، لغو توکن و ... را انجام دهند. ابتدا در مسیر روت پروژه دستور زیر را اجرا می‌کنیم: 

php artisan vendor:publish --tag=passport-components

خروجی به دست آمده از اجرای دستور فوق در شکل زیر نشان داده شده است:

با این کار کامپوننت‌های Vue مربوط به پاسپورت ایجاد می‌شوند و در دایرکتوری /resources/assets/js/components قرار می‌گیرند.

اگر به فهرست این دایرکتوری نگاه کنید، باید یک پوشه با نام پاسپورت را با سه مؤلفه Vue در داخل آن ببینید: 

پس از انتشار کامپوننت ها، باید آن‌ها را داخل برنامه بارگذاری کنیم تا بتوانیم از آن‌ها استفاده کنیم. برای این کار فایل /resources/assets/js/app.js را باز کنید و کامپوننت‌های Vue زیر را ثبت کنید. توجه کنید که این کامپوننت‌ها باید قبل از خط const app = new Vue({… اضافه شوند.

// …

Vue.component(
    'passport-clients',
    require('./components/passport/Clients.vue').default
);

Vue.component(
    'passport-authorized-clients',
    require('./components/passport/AuthorizedClients.vue').default
);

Vue.component(
    'passport-personal-access-tokens',
    require('./components/passport/PersonalAccessTokens.vue').default
);

const app = new Vue({
    el: '#app'
});

سپس برای نصب پکیج‌های Node و بازسازی (rebuild) asset‌ها با استفاده از webpack، باید دستورات npm زیر را اجرا کنیم. مطمئن شوید که npm run dev برای کامپایل مجدد اجرا شده باشد. توجه داشته باشید که می‌توانید به جای آن از npm run watch نیز استفاده کنید تا rebuild های بعدی به صورت خودکار انجام شود اما فعلا به آن نیازی نداریم.

npm install
npm run dev

تگ‌های زیر مربوط به 3 کامپوننت پاسپورت می‌باشد که می‌خواهیم آن‌ها را در یکی از تمپلیت‌های برنامه خود بنویسیم تا شروع به ایجاد کلاینت و personal access tokens کنیم.

<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>

 

پیاده سازی بخش تنظیمات OAuth

 
اکنون باید یک صفحه تنظیمات ایجاد کنیم که نمایش پاسپورت در آن قرار گیرد. با استفاده از دستور زیر، یک کنترلر جدید ایجاد می‌کنیم:

php artisan make:controller SettingsController

کد زیر را در این کنترلر می‌نویسیم. همان‌طور که مشاهده می‌شود یک middleware تنظیم شده است که فقط به کاربرانی که احراز هویت شده‌اند، اجازه دسترسی به متد index را می‌دهد:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SettingsController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index()
    {
        return view('settings');
    }
}

در ادامه یک فایل view جدید با نام settings.blade.php را در مسیر /resources/views ایجاد می‌کنیم و کد زیر را درون آن قرار می‌دهیم. در این کد، ما کامپوننت‌های Vue مربوط به پاسپورت را که قبلا ثبت و معرفی کرده بودیم به نمای خود اضافه کردیم. این کامپوننت‌ها، به راحتی یک ابزار کامل مدیریت OAuth برای کاربر ایجاد می‌کند.

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <passport-authorized-clients></passport-authorized-clients>
                <passport-clients></passport-clients>
                <passport-personal-access-tokens></passport-personal-access-tokens>
            </div>
        </div>
    </div>
@endsection

اکنون نیاز است برای نمایش دادن کنترلر و view خود، یک route ایجاد کنیم. فایل /routes/web.php را باز کرده و route زیر را به آن اضافه می‌کنیم:

// …

Route::get('/settings', 'SettingsController@index')->name('settings');

در انتها برای این که این صفحه در دسترس باشد، در صفحه یک لینک به Setting اضافه می‌کنیم. برای این کار فایل resources/views/layouts/app.blade.php/ را باز کرده و بالای خط مربوط به Logout، کد زیر را اضافه می‌کنیم. این کد یک لینک به صفحه تنظیمات ایجاد می‌کند.

// …

<a class="dropdown-item" href="{{ route('settings') }}">{{ __('Settings') }}</a>

// …

دستور php artisan serve را اجرا می‌کنیم و به لینک http://127.0.0.1:8000 رفته و سپس وارد سیستم می‌شویم و روی Name > Settings کلیک می‌کنیم:

باید صفحه‌ای مانند شکل زیر را مشاهده کنیم:

ایجاد یک API Route برای تست سرور OAuth

 تا اینجای کار ما با استفاده از پاسپورت، یک سرور OAuth راه‌اندازی کردیم. در این مرحله باید مسیر API را ایجاد کنیم. به درخواست‌هایی که به این مسیر می‌آید، با استفاده از پاسپورت پاسخ داده می‌شود. قبل از این که بخواهیم مسیر API خود را ایجاد کنیم، لازم است در مورد محافظت از مسیر‌ها توضیحاتی دهیم. 

برای محافظت از مسیر ها باید مراحل زیر انجام شود :

1-     محافظت از طریق Middleware

 پاسپورت شامل یک محافظ احراز هویت (authentication guard) است که برای تایید access token‌ها در درخواست‌ها استفاده می‌شود. وقتی که محافظ api را برای استفاده از درایور Passport تنظیم کردیم، فقط باید middleware یا میان افزار auth: api را در هر مسیری که به یک access token معتبر نیاز دارد، مشخص کنیم. برای مثال در تکه کد زیر در فایل routes/api.php، برای مسیری با نام user/ نیاز به access token معتبر می‌باشد، به همین جهت از middleware auth:api استفاده شده است:

Route::get('/user', function () {
    //
})->middleware('auth:api');

گاهی لازم است از چندین محافظ احراز هویت استفاده کنیم. اگر برنامه ما انواع مختلفی از کاربران را که ممکن است از مدل‌های کاملا متفاوت Eloquent استفاده کنند، احراز هویت کند، به احتمال زیاد نیاز داریم که برای هر نوع user provider در برنامه خود، پیکربندی محافظ تعریف کنیم. با این کار می‌توانیم از درخواست‌های کاربران خاص محافظت کنیم. به عنوان مثال، فایل پیکربندی config/auth.php به صورت زیر خواهد بود:

'api' => [
    'driver'   => 'passport',
    'provider' => 'users',
],

'api-customers' => [
    'driver'   => 'passport',
    'provider' => 'customers',
],

در تکه کد زیر از محافظ api-customers، برای تایید اعتبار درخواست های ورودی مسیر /customer استفاده شده است:

Route::get('/customer', function () {
    //
})->middleware('auth:api-customers');

2-    ارسال access token به برنامه

 هنگام فراخوانی مسیر‌هایی که به وسیله Passport محافظت شده‌اند، کلاینت هایی که از API  برنامه ما استفاده می‌کنند، باید access token خودشان را به عنوان Bearer token در هدر authorization درخواست خود مشخص کنند. به عنوان مثال، هنگام استفاده از کتابخانه Guzzle HTTP به صورت زیر خواهیم داشت:

$response = $client->request('GET', '/api/user', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],
]);

اکنون که در مورد محافظت از مسیر‌ها اطلاعاتی به دست آوردیم به سراغ ادامه پیاده سازی می‌رویم.

برای ایجاد مسیر API، ابتدا فایل routes/api.php/ را باز می‌کنیم و مانند زیر یک مسیر را با middleware auth:api تنظیم می‌کنیم به این معنی که فقط برنامه‌های احراز هویت شده با لاراول پاسپورت اجازه دسترسی به این مسیر را دارند. بعد از تایید اعتبار، بر اساس کدی که return شده است، همه task های کاربر را برای آن‌ها بر می‌گرداند. 

Route::middleware('auth:api')->get('/todos', function (Request $request) {
    return $request->user()->tasks;
});

تبریک می‌گوییم. شما با موفقیت یک سرور OAuth ایجاد کردید. اکنون کاربران شما می‌توانند برنامه‌هایی را ایجاد کنند که بتوانند بدون استفاده از نام کاربری و رمز عبور و فقط با استفاده از Access Token به برنامه دسترسی پیدا کنند.

اکنون سرور OAuth آماده سرویس دهی به برنامه‌های third-party  می‌باشد . در بخش‌های بعدی به صدور access token  و همچنین پاسخ دهی به درخواست های برنامه‌های دیگر بر اساس انواع مجوز، می‌پردازیم.

online-support-icon