API Authentication (Passport) trong Laravel
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 AP I 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ử ...
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.
Để 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 LaravelPassportHasApiTokens vào mô hình AppUser 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 LaravelPassportHasApiTokens; use IlluminateNotificationsNotifiable; use IlluminateFoundationAuthUser 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 AppProviders; use LaravelPassportPassport; use IlluminateSupportFacadesGate; use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ 'AppModel' => 'AppPoliciesModelPolicy', ]; /** * 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', ], ],
Để 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>
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
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 CarbonCarbon; /** * 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)); }
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.
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ệnhclient,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ạnclient ID` và bí mật:
php artisan passport:client
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 => { // });
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); });
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
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 GuzzleHttpClient; $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.
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 GuzzleHttpClient; $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.