API Authentication (Passport) trong Laravel
Bài đăng này đã không được cập nhật trong 6 năm
Introduction
Laravel đã làm cho việc thực hiện xác thực qua các form đăng nhập truyền thống trở nên dễ dàng, nhưng API là về những cái gì? Các API thường sử dụng mã để xác thực người dùng và không duy trì trạng thái phiên giữa các yêu cầu. Laravel làm cho việc xác thực API trở nên dễ dàng bằng cách sử dụng Laravel Passport
, cung cấp triển khai máy chủ OAuth2 hoàn chỉnh cho ứng dụng Laravel của bạn chỉ trong vài phút. Passport được xây dựng trên đầu trang của máy chủ League OAuth2 server OAuth2 League được duy trì bởi Alex Bilbie
.
Installation
Để bắt đầu, hãy cài đặt Passport
qua trình quản lý gói của Composer
:
composer require laravel/passport
Nhà cung cấp dịch vụ Passport
đăng ký thư mục di trú cơ sở dữ liệu riêng của mình với framework, vì vậy bạn nên di chuyển cơ sở dữ liệu của bạn sau khi đăng ký nhà cung cấp. Việc di chuyển Passport
sẽ tạo ra các bảng mà ứng dụng của bạn cần để lưu trữ clients
và các access tokens
:
php artisan migrate
Nếu bạn không sử dụng di chuyển mặc định của Passport
, bạn nên gọi phương thức: Passport::ignoreMigrations
theo phương thức register
của AppServiceProvider
. Bạn có thể xuất các di chuyển mặc định bằng cách sử dụng nhà cung cấp thủ công php artisan vendor:publish --tag=passport-migrations.
Tiếp theo, bạn nên chạy lệnh passport:install
. Lệnh này sẽ tạo ra các khoá mã hóa cần thiết để tạo các mã thông báo truy cập an toàn. Thêm vào đó, lệnh sẽ tạo ra các clients
hàng "truy cập cá nhân" và "cấp mật khẩu" sẽ được sử dụng để tạo các mã truy cập:
php artisan passport:install
Sau khi chạy lệnh này, thêm tính năng Laravel\Passport\HasApiTokens
vào mô hình App\User
của bạn. Đặc điểm này sẽ cung cấp một số phương pháp giúp đỡ cho mô hình của bạn cho phép bạn kiểm tra mã thông báo và phạm vi của người dùng đã được xác thực:
<?php
namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
Tiếp theo, bạn nên gọi phương thức Passport::routes
trong phương thức boot của AuthServiceProvider
. Phương pháp này sẽ đăng ký các tuyến đường cần thiết để phát access token
và thu hồi các access token
, clients
và các access token
cá nhân:
<?php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
Cuối cùng, trong tệp cấu hình config/auth.php
bạn nên đặt tùy chọn driver của bộ phận xác thực api
vào passport
. Điều này sẽ hướng dẫn ứng dụng của bạn sử dụng TokenGuard
của Passport
khi xác thực các yêu cầu API đến:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Frontend Quickstart
Để sử dụng các thành phần Passport Vue components
, bạn phải sử dụng framework Vue JavaScript
. Các thành phần này cũng sử dụng framework Bootstrap CSS. Tuy nhiên, ngay cả khi bạn không sử dụng các công cụ này, các thành phần này sẽ đóng vai trò là một tài liệu tham khảo có giá trị cho việc triển khai phần đầu của bạn.
Passport
đi kèm với JSON API
mà bạn có thể sử dụng để cho phép người dùng tạo clients và các token truy cập. Tuy nhiên, có thể mất nhiều thời gian để mã lối vào để tương tác với các API này. Vì vậy, Passport
cũng bao gồm các thành phần Vue
được xây dựng sẵn mà bạn có thể sử dụng như là một ví dụ về việc triển khai hoặc bắt đầu cho việc thực hiện của bạn.
Để xuất bản các thành phần Passport Vue
, sử dụng lệnh nhà cung cấp vendor:publish
:
php artisan vendor:publish --tag=passport-components
Các thành phần được xuất bản sẽ được đặt trong thư mục resources/assets/js/components
. Khi các thành phần đã được xuất bản, bạn nên đăng ký chúng trong tệp resources/assets/js/app.js
:
Vue.component(
'passport-clients',
require('./components/passport/Clients.vue')
);
Vue.component(
'passport-authorized-clients',
require('./components/passport/AuthorizedClients.vue')
);
Vue.component(
'passport-personal-access-tokens',
require('./components/passport/PersonalAccessTokens.vue')
);
Sau khi đăng ký các thành phần, hãy chắc chắn để chạy npm run dev
để biên dịch lại assets. Khi bạn đã biên dịch lại assets
, bạn có thể bỏ các thành phần vào một trong các mẫu của ứng dụng để bắt đầu tạo clients
and access tokens
cá nhân:
<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>
Deploying Passport
Khi triển khai Passport
đến các máy chủ sản xuất của bạn lần đầu tiên, có thể bạn cần phải chạy lệnh passport:keys
. Lệnh này tạo ra các khoá mật mã Yêu cầu Passport
để tạo mã thông báo truy cập. Các phím được tạo ra không thường được giữ trong kiểm soát nguồn:
php artisan passport:keys
Configuration
Token Lifetimes
Theo mặc định,Passport
phát hành các mã thông báo truy cập lâu dài mà không cần phải làm mới. Nếu bạn muốn định cấu hình vòng đời mã thông báo ngắn hơn, bạn có thể sử dụng các phương thức tokensExpireIn
và refreshTokensExpireIn
. Những phương pháp này nên được gọi từ phương thức boot của AuthServiceProvider
:
use Carbon\Carbon;
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
}
Issuing Access Tokens
Sử dụng OAuth2
với mã ủy quyền là cách mà hầu hết các nhà phát triển đều quen thuộc với OAuth2
. Khi sử dụng mã ủy quyền, một ứng dụng client application
chuyển hướng người dùng đến máy chủ của bạn, nơi họ sẽ phê duyệt hoặc từ chối yêu cầu phát hành một access token
tới client
.
Managing Clients
Thứ nhất, các nhà phát triển xây dựng các ứng dụng cần tương tác với API
của ứng dụng của bạn sẽ cần phải đăng ký ứng dụng của họ với ứng dụng của bạn bằng cách tạo ra một "client"
. Thông thường, điều này bao gồm cung cấp tên của ứng dụng của họ và URL mà ứng dụng của bạn có thể chuyển hướng đến sau khi người dùng chấp nhận yêu cầu ủy quyền của họ.
Lệnh passport:client
Cách đơn giản nhất để tạo ra một client
là sử dụng lệnh passport:client
. Lệnh này có thể được sử dụng để tạo ra các khách hàng của chính bạn để thử nghiệm chức năng OAuth2của bạn. Khi bạn chạy lệnh
client,
Passportsẽ nhắc nhở bạn để biết thêm thông tin về
clientcủa bạn và sẽ cung cấp cho bạn
client ID` và bí mật:
php artisan passport:client
JSON API
Vì người dùng của bạn sẽ không thể sử dụng lệnh client
, Passport
cung cấp một API JSON
mà bạn có thể sử dụng để tạo clients. Điều này giúp bạn tiết kiệm được sự cố khi phải tự kiểm soát mã để tạo, cập nhật và xóa các máy khách.
Tuy nhiên, bạn sẽ cần phải ghép nối API JSON
của Passport với giao diện người dùng của riêng bạn để cung cấp bảng điều khiển cho người dùng để quản lý client của họ. Dưới đây, chúng tôi sẽ xem xét tất cả các điểm cuối API
để quản lý client
. Để thuận tiện, chúng tôi sẽ sử dụng Axios để chứng minh việc yêu cầu HTTP tới các điểm cuối.
Nếu bạn không muốn thực hiện toàn bộ giao diện quản lý client của mình, bạn có thể sử dụng frontend quickstart để có một frontend đẩy đủ chức năng chỉ trong vài phút
GET /oauth/clients
Đường dẫn này trả về tất cả các client
cho người dùng đã được chứng thực. Điều này chủ yếu hữu ích cho việc liệt kê tất cả các client
của người dùng để họ có thể chỉnh sửa hoặc xóa chúng:
axios.get('/oauth/clients')
.then(response => {
console.log(response.data);
});
POST /oauth/clients
Đường dẫn này được sử dụng để tạo ra các client mới. Nó đòi hỏi hai mẩu dữ liệu: client's name và một redirect URL
. redirect URL
là nơi người dùng sẽ được chuyển hướng sau khi phê duyệt hoặc từ chối yêu cầu ủy quyền.
Khi khách hàng được tạo ra, nó sẽ được cấp một client ID
và client bí mật. Các giá trị này sẽ được sử dụng khi yêu cầu access tokens
từ ứng dụng của bạn. Client
tạo đường dẫn route will return the new client instance:
khách hàng mới. tên của khách hàng và một URL
chuyển hướng. URL
chuyển hướng
ID khách hàng và bí mật khách hàng. truy cập các mã số truy cập. Tuy trình tạo khách hàng sẽ trả về trường hợp khách hàng mới:
const data = {
name: 'Client Name',
redirect: 'http://example.com/callback'
};
axios.post('/oauth/clients', data)
.then(response => {
console.log(response.data);
})
.catch (response => {
// List errors on response...
});
PUT /oauth/clients/{client-id}
Route này được sử dụng để cập nhật khách hàng. Nó đòi hỏi hai mẩu dữ liệu: tên của khách hàng và một URL
chuyển hướng. URL
chuyển hướng là nơi người dùng sẽ được chuyển hướng sau khi phê duyệt hoặc từ chối yêu cầu ủy quyền. Các tuyến đường sẽ trả lại các ví dụ khách hàng cập nhật:
const data = {
name: 'New Client Name',
redirect: 'http://example.com/callback'
};
axios.put('/oauth/clients/' + clientId, data)
.then(response => {
console.log(response.data);
})
.catch (response => {
// List errors on response...
});
DELETE /oauth/clients/{client-id}
This route is used to delete clients:
axios.delete('/oauth/clients/' + clientId)
.then(response => {
//
});
Requesting Tokens
Redirecting For Authorization
Khi khách hàng đã được tạo, các nhà phát triển có thể sử dụng ID khách hàng và bí mật của họ để yêu cầu mã ủy quyền và truy cập mã thông báo từ ứng dụng của bạn. Thứ nhất, ứng dụng tiêu thụ phải tạo một yêu cầu chuyển hướng tới đường dẫn / oauth / autoclick
của ứng dụng của bạn như sau:
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
});
Approving The Request
Khi được requests
, Passport sẽ tự động hiển thị một mẫu cho người dùng cho phép họ chấp thuận hoặc từ chối yêu cầu ủy quyền. Nếu họ chấp thuận yêu cầu, chúng sẽ được chuyển hướng lại đến redirect_uri
đã được xác định bởi ứng dụng tiêu thụ. Redirect_uri
phải khớp với URL
chuyển hướng đã được chỉ định khi khách hàng được tạo.
Nếu bạn muốn tùy chỉnh màn hình phê duyệt ủy quyền, bạn có thể xuất bản quan điểm của Passport
bằng cách sử dụng nhà cung cấp các lệnh Artisan. Các chế độ xem được xuất bản sẽ được đặt trong resources/views/vendor/passport:
php artisan vendor:publish --tag=passport-views
Chuyển đổi mã ủy quyền để truy cập Tokens
Nếu người dùng chấp thuận yêu cầu ủy quyền, họ sẽ được chuyển hướng trở lại ứng dụng tiêu dùng. Người tiêu dùng sau đó sẽ gửi yêu cầu POST
cho ứng dụng của bạn để yêu cầu mã thông báo truy cập. Yêu cầu phải bao gồm mã ủy quyền do ứng dụng của bạn phát hành khi người dùng chấp thuận yêu cầu ủy quyền. Trong ví dụ này, chúng ta sẽ sử dụng thư viện Guzzle HTTP
để thực hiện yêu cầu POST
:
Route::get('/callback', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'redirect_uri' => 'http://example.com/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});
Route này /oauth/token
sẽ trả về phản hồi JSON
chứa các thuộc tính access_token
, refresh_token
và expires_in
. Thuộc tính expires_in
chứa số giây cho đến khi mã thông báo truy cập hết hạn.
Làm mới Tokens
Nếu ứng dụng của bạn phát hành các thẻ truy cập ngắn, người dùng sẽ cần phải làm mới các thẻ truy cập của họ thông qua mã thông báo đã được cung cấp cho họ khi mã thông báo truy cập được phát hành. Trong ví dụ này, chúng ta sẽ sử dụng thư viện Guzzle HTTP
để làm mới mã thông báo:
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => 'the-refresh-token',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
Route /oauth/token
sẽ trả về JSON chứa các thuộc tính access_token
, refresh_token
, và expires_in
. Trong đó expires_in
sẽ tính số giây cho đến khi token hết hạn.
- Tài liệu tham khảo : https://laravel.com/docs/5.5/passport
All rights reserved