در فصل های گذشته با انواع grant در OAuth و همچنین laravel passport آشنا شدیم. بعضی از انواع احراز هویت دیگری هستند که زیاد مورد اقبال نیستند و یا حتی مشکلات امنیتی نیز برای آنها ذکر شده است که در فصل های گذشته درباره ی آن شرح دادیم. در این بخش به پیاده سازی این موارد در پاسپورت میپردازیم.
این روش های تولید توکن عبارتند از:
· Implicit Grant Tokens
· Client Credentials Grant Tokens
· Personal Access Tokens
در ادامه به بررسی این موارد خواهیم پرداخت.
Implicit Grant Tokens
نوع Implicit Grant شبیه به authorization code grant است. اما توکن بدون تبادل یک authorization code به کلاینت برگردانده میشود. این نوع بیشتر برای برنامههای جاوااسکریپت ، برنامههای تلفن همراه یا در جایی که client credential قابل ذخیرهسازی نیست، استفاده میشود. برای فعال کردن grant در laravel passport ، باید متد enableImplicitGrant را در کلاس AuthServiceProvider فراخوانی کنید:
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::enableImplicitGrant();
{
پس از فعال کردن این grant، توسعهدهندگان ممکن است از client ID خود استفاده کنند تا access token را از برنامه شما بخواهند. برنامه کلاینت باید یک درخواست تغییر مسیر یا redirect را به مسیر oauth/authorize/ برنامه شما مانند زیر ارسال کند:
Route::get('/redirect', function (Request $request) {
$request->session()->put('state', $state = Str::random(40));
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'token',
'scope' => '',
'state' => $state,
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
});
به یاد داشته باشید که مسیر /oauth/authorize از قبل با متد Passport::routes تعریف شده است و نیازی به تعریف دستی آن نیست.
Client Credentials Grant Tokens
Client Credentials Grant برای تایید اعتبار machine-to-machine مناسب است. به عنوان مثال، شما ممکن است این grant را در یک کار برنامهریزی شده (Cron job) انجام دهید که وظایف نگهداری از طریق API را انجام میدهد.
قبل از این که برنامه شما بتواند از طریق client credential، توکنها را صادر کند، نیاز دارید یک کلاینت از نوع client credential grant ایجاد کنید. میتوانید این کار را با استفاده از گزینه --client در دستور passport:client ایجاد کنید:
php artisan passport:client --client
در مرحله بعد، برای استفاده از این grant type، نیاز دارید middleware به نام CheckClientCredentials را به property $routeMiddleware در فایل app/Http/Kernel.php اضافه کنید:
use Laravel\Passport\Http\Middleware\CheckClientCredentials;
// …
protected $routeMiddleware = [
// …
'client' => CheckClientCredentials::class,
];
سپس، middleware را به یک مسیر وصل کنید:
// …
Route::get('/orders', function (Request $request) {
// …
})->middleware('client');
// …
برای محدود کردن دسترسی مسیر به scopeهای خاص، میتوانید هنگام اتصال سرویس middleware کلاینت به مسیر، لیست کاملی از scopeهای مورد نیاز را تهیه کنید:
// …
Route::get('/orders', function (Request $request) {
// …
})->middleware('client:check-status,your-scope');
// …
بازیابی توکنها (Retrieving Tokens)
برای بازیابی یک توکن با استفاده از این grant type، مانند تکه کد زیر باید یک درخواست به مسیر oauth/token ایجاد کنید:
// …
$guzzle = new GuzzleHttp\Client;
$response = $guzzle->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => 'your-scope',
],
]);
return json_decode((string) $response->getBody(), true)['access_token'];
// …
Personal Access Tokens
بعضی اوقات، کاربران شما ممکن است بخواهند بدون عبور از جریان تغییر مسیر authorization code، access token را برای خود صادر کنند. خوب است به کاربران اجازه دهیم تا از طریق رابط کاربری برنامه، برای خود access token صادر کنند. این قابلیت علاوه بر این که امکان آزمایش API شما را فراهم میکند میتواند به طور کلی یک رویکرد سادهتر برای صدور access token باشد.
ایجاد یک Personal Access Token
برای صدور یک personal access token ابتدا باید یک personal access client ایجاد کرد. برای این کار از دستور pasport: client با گزینه --personal استفاده میشود. اگر قبلا دستور passport:install را اجرا کرده باشید، نیازی به اجرای این دستور نیست:
php artisan passport:client --personal
بعد از ایجاد personal access client میتوانید، client ID و client secret را به صورت زیر در فایل .env برنامه خود قرار دهید:
PASSPORT_PERSONAL_ACCESS_CLIENT_ID=client-id-value
PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET=unhashed-client-secret-value
در مرحله بعد، باید این مقادیر را با فراخوانی متدهای Passport::personalAccessClientId و Passport::personalAccessClientSecret در متد boot از کلاس AuthServiceProvider، ثبت کنید:
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::personalAccessClientId(
config('passport.personal_access_client.id')
);
Passport::personalAccessClientSecret(
config('passport.personal_access_client.secret')
);
// …
}
مدیریت Personal Access Tokens
بعد از این که یک personal access token ایجاد کردید، میتوانید با استفاده از متد createToken یک شی از مدل user، توکنهایی را برای یک کاربر خاص صادر کنید. متد createToken نام توکن را به عنوان اولین ورودی و یک آرایه اختیاری از scopeها را به عنوان ورودی دوم میپذیرد:
$user = App\User::find(1);
// Creating a token without scopes...
$token = $user->createToken('Token Name')->accessToken;
// Creating a token with scopes...
$token = $user->createToken('My Token', ['place-orders'])->accessToken
JSON API
پاسپورت شامل JSON API برای مدیریت personal access token است. ممکن است این مورد را با front-end شخصی خود آماده کنید تا داشبوردی را برای مدیریت personal access token به کاربران خود ارائه دهید. در ادامه، تمام endpoint های API که برای مدیریت personal access token نیاز است، بررسی خواهیم کرد. برای راحتی، از Axios برای نشان دادن درخواست HTTP به endpoint استفاده میشود.
JSON API توسط middlewareهای auth و web محافظت میشود. بنابراین، فقط از برنامه شخصی شما فراخوانی شده و قادر به فراخوانی از منبع خارجی نیست.
نکته: اگر نمی خواهید front-endمخصوص خود را برای personal access token پیاده سازی کنید، میتوانید از front-end quickstart، برای داشتن یک ظاهر کاملا کاربردی در چند دقیقه استفاده کنید.
1- این مسیر کلیه scopeهای تعریف شده برای برنامه شما را برمی گرداند.
GET /oauth/scopes
شما میتوانید از این مسیر برای لیست scopeهایی که کاربر ممکن است به personal access token اختصاص دهد، استفاده کنید:
axios.get('/oauth/scopes')
.then(response => {
console.log(response.data);
});
2- این مسیر کلیه personal access tokenها را که کاربر احراز هویت شده ایجاد کرده است برمی گرداند.
GET /oauth/personal-access-tokens
این کار برای ویرایش و حذف لیست تمام توکن های کاربر مفید میباشد:
axios.get('/oauth/personal-access-tokens')
.then(response => {
console.log(response.data);
});
3- این مسیر personal access token جدید ایجاد میکند.
POST /oauth/personal-access-tokens
به دو قطعه داده نیاز دارد. نام آن و scope هایی که باید به توکن اختصاص داده شوند:
const data = {
name: 'Token Name',
scopes: []
};
axios.post('/oauth/personal-access-tokens', data)
.then(response => {
console.log(response.data.accessToken);
})
.catch (response => {
// List errors on response...
});
4- این مسیر میتواند برای پاک کردن personal access token استفاده شود:
DELETE /oauth/personal-access-tokens/{token-id}
و کد زیر برای انجام این هدف:
axios.delete('/oauth/personal-access-tokens/' + tokenId);
همانطور که مشاهده کردید علاوه بر انواع Grant که در فصل های گذشته به صورت کامل آنها را بررسی کردیم، روش های دیگری نیز وجود دارد اما کمتر مورد استفاده قرار میگیرند. برای مثال Implicit یکی از انواعی است که در مستند Passport استفاده از آن پیشنهاد نشده است. به همین جهت در این فصل خلاصه ای از عملکرد آنها را خدمت شما همراهان گرامی، بیان کردیم.