Làm Sao Để Xây Dựng Một Bảo Vệ Xác Thực Trong Laravel
https://code.tutsplus.com/vi/tutorials/how-to-create-a-custom-authentication-guard-in-laravel--cms-29667
Làm Sao Để Xây Dựng Một Bảo Vệ Xác Thực Trong Laravel
by Sajal Soni9 Nov 2017Difficulty:IntermediateLength:LongLanguages:EnglishDeutschEspañolFrançaisBahasa IndonesiaMelayuPусскийTiếng ViệtLaravel 5PHPWeb Development
Vietnamese (Tiếng Việt) translation by Andrea Ho (you can also view the original English article)
Trong bài này, chúng tôi sẽ giới thiệu về hệ thống xác thực trong framework Laravel. Mục đích chính của bài viết này là để tạo ra một bảo vệ xác thực tùy biến bằng cách mở rộng hệ thống xác thực cốt lõi.
Laravel cung cấp một hệ thống xác thực rất vững chắc trong cốt lõi của framework, giúp thực hiện tác vụ xác thực cơ bản một cách dễ dàng. Trong thực tế, bạn chỉ cần chạy một vài lệnh artsan để thiết lập phần khung cơ bản của một hệ thống xác thực.
Hơn nữa, bản thân hệ thống được thiết kế theo cách mà bạn có thể mở rộng nó và gắn kết với những adapter xác thực tự biên của bạn. Đó là những chi tiết chúng ta sẽ thảo luận trong xuyên suốt bài viết này. Trước khi chúng tôi tiếp tục và đào sâu vào việc triển khai của phần bảo vệ xác thực tự biên, chúng ta sẽ bắt đầu với phần thảo luận các yếu tố cơ bản của hệ thống xác thực từ Laravel - guards và providers.
Thành phần cốt lõi: Guard và Provider
Hệ thống xác thực của Laravel được xây dựng từ hai thành phần cốt lõi - guard và provider.
Guards
Bạn có thể nghĩ một guard như một cách cung cấp logic được dùng để xác định người dùng được chứng thực. Trong cốt lõi, Laravel cung cấp nhiều guard khác nhau như session hoặc token. Một session guard duy trì trạng thái của người dùng trong mỗi request bằng cookie, và mặt khác, token guard xác thực người dùng bằng cách kiểm tra một token hợp lệ trong mỗi request.
Vì vậy, như bạn thấy, guard xác định logic của việc xác thực, và không cần thiết để luôn xác thực bằng cách lấy các thông tin hợp lệ từ phía back-end. Bạn có thể triển khai một guard mà chỉ cần kiểm tra sự có mặt của một thông tin cụ thể trong headers của request và xác thực người dùng dựa trên điều đó.
Phần sau của bài viết, chúng ta sẽ triển khai một guard để kiểm ra các tham số JSON nhất định trong headers của request và lấy ra người dùng hợp lệ từ MongoDB back-end.Advertisement
Providers
Nếu guard định nghĩa logic của việc chứng thực, thì provider của chứng thực có trách nhiệm lấy ra người dùng từ phần lưu trữ của back-end. Nếu guard yêu cầu người dùng phải hợp lệ với bộ lưu trữ của back-end thì việc triển khai truy xuất người dùng sẽ được chuyển tới provider của việc xác thực.
Laravel mang đến hai provider chứng thực mặc định - Database và Eloquent. Provider của xác thực Database xử lý nhiệm vụ trực tiếp lấy thông tin của người dùng từ bộ lưu trữ ở back-end, còn Eloquent cung cấp một abstraction layer cần thiết để làm việc này.
Trong ví dụ, chúng ta sẽ triển khai một provider xác thực của MongoDB để lấy thông tin người dùng từ back-end của MongoDB.
Vậy đó là giới thiệu cơ bản về guards và providers trong hệ thống xác thực của Laravel. Từ phần tiếp theo trở đi, chúng ta sẽ tập trung vào việc phát triển của bộ bảo vệ chứng thực tự biên và provider!
Sơ lược về Cài đặt File
Hãy lướt nhanh qua danh sách file mà chúng ta sẽ triển khai trong suốt hành trình của bài viết này.
config/auth.php
: Đây là file cấu hình xác thực mà chúng ta sẽ thêm vào một giá trị của phần bảo vệ của chúng ta.config/mongo.php
: Đây là file lưu giữ cấu hình MongoDB.app/Services/Contracts/NosqlServiceInterface.php:
Đây là một interface mà class database của Mongo sẽ implement.app/Database/MongoDatabase.php
: Đây là một class database để tương tác với MongoDB.app/Models/Auth/User.php
: đây là class User model để triển khai Authenticable contract.app/Extensions/MongoUserProvider.php:
là phần triển khai của provider của việc xác thực.app/Services/Auth/JsonGuard.php:
là phần triển khai của driver của guard của việc xác thực.app/Providers/AuthServiceProvider.php:
đây là một file hiện thời chúng tôi sẽ dùng để bổ sung việc gắn kết container của service của chúng ta.app/Http/Controllers/MongoController.php:
đây là demo cho file controller mà chúng ta sẽ triển khai để kiểm tra guard tự biên của chúng ta.
Đừng lo lắng nếu danh sách của các file không có rõ ràng khi chúng ta thảo luận mọi thứ chi tiết khi chúng ta xem xét chúng kỹ càng.
Đi sâu vào phần triển khai
Trong phần này, chúng ta sẽ xem kỹ phần triển khai của những file được yêu cầu:
Điều trước tiên chúng ta cần làm là thông báo cho Laravel về guard của chúng ta. Tiếp tục nhập những chi tiết của guard và file config/auth.php như đã hiển thị.
0102030405060708091011121314151617181920
......'guards'
=> [ 'web'
=> [ 'driver'
=>
'session', 'provider'
=>
'users', ],
'api'
=> [ 'driver'
=>
'token', 'provider'
=>
'users', ],
'custom'
=> [ 'driver'
=>
'json', 'provider'
=>
'mongo', ],],......
Như bạn đã thấy, chúng ta đã bổ sung guard tự biên vào bên dưới custom key.
Tiếp theo, chúng ta cần nhập bổ sung thông tin của một provider được tương tác trong phần providers.
010203040506070809101112131415161718
......'providers'
=> [ 'users'
=> [ 'driver'
=>
'eloquent', 'model'
=> App\User::class, ], 'mongo'
=> [ 'driver'
=>
'mongo' ],
// 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ],],......
Chúng ta đã bổ sung provider bên dưới mongo key.
Cuối cùng, hãy thay đổi guard xác thực mặc định từ web sang custom.
12345678
......'defaults'
=> [ 'guard'
=>
'custom', 'passwords'
=>
'users',],......
Dĩ nhiên nó sẽ chưa hoạt động, khi chúng ta chưa triển khai các file cần thiết. Và đó là điều mà chúng ta sẽ thảo luận trong những phần kế đến.
Cài đặt Driver của MongoDB
Trong phần này, chúng tôi sẽ triển khai các file cần thiết để giao tiếp với giá trị MongoDB.
Đầu tiên hãy tạo một file cấu hình config/mongo.php
sẽ lưu những thiết lập kết nối mặc định cho MongoDB.
12345678
<?phpreturn
[ 'defaults'
=> [ 'host'
=>
'{HOST_IP}', 'port'
=>
'{HOST_PORT}', 'database'
=>
'{DB_NAME}' ]];
Dĩ nhiên, bạn cần phải thay đổi các giá trị placeholder theo thiết lập của bạn.
Thay vì trực tiếp tạo một class tương tác với MongoDB, chúng ta sẽ tạo một interface ngay từ đầu.
Lợi ích của việc tạo một interface là nó cung cấp một contract mà mỗi developer cần phải tuân theo trong khi triển khai nó. Đồng thời, triển khai của chúng ta cho MongoDB có thể dễ dàng thay đổi bằng một triển khai NoSQL khác nếu cần thiết.
Tiếp tục và tạo một file interface app/Services/Contracts/NosqlServiceInterface.php
với nôi dung như sau:
01020304050607080910111213141516171819202122232425262728293031323334353637383940414243
<?php// app/Services/Contracts/NosqlServiceInterface.phpnamespace
App\Services\Contracts;
Interface NosqlServiceInterface{ /** * Create a Document * * @param string $collection Collection/Table Name * @param array $document Document * @return boolean */ public
function
create($collection, Array
$document);
/** * Update a Document * * @param string $collection Collection/Table Name * @param mix $id Primary Id * @param array $document Document * @return boolean */ public
function
update($collection,
$id, Array
$document);
/** * Delete a Document * * @param string $collection Collection/Table Name * @param mix $id Primary Id * @return boolean */ public
function
delete($collection,
$id);
/** * Search Document(s) * * @param string $collection Collection/Table Name * @param array $criteria Key-value criteria * @return array */ public
function
find($collection, Array
$criteria);}
Đây là một interface khá đơn giản để khai báo các phương thức CRUD mà một class phải định nghĩa khi implement interface này.
Giờ hãy định nghĩa một class thực sự ở app/Database/MongoDatabase.php.
0102030405060708091011121314151617181920212223242526272829
<?php// app/Database/MongoDatabase.phpnamespace
App\Database;
use
App\Services\Contracts\NosqlServiceInterface;
class
MongoDatabase
implements
NosqlServiceInterface{ private
$connection; private
$database;
public
function
__construct($host,
$port,
$database) { $this->connection =
new
MongoClient(
"
mongodb://
{$host}:{$port}"
); $this->database =
$this->connection->{$database}; }
/** * @see \App\Services\Contracts\NosqlServiceInterface::find() */ public
function
find($collection, Array
$criteria) { return
$this->database->{$collection}->findOne($criteria); }
public
function
create($collection, Array
$document) {} public
function
update($collection,
$id, Array
$document) {} public
function
delete($collection,
$id) {}}
Dĩ nhiên, tôi giả định rằng bạn đã cài đặt MongoDB và extension tương ứng MongoDB của PHP.
Phương thức __construc
t khởi tạo class MongoClient
với các tham số cần thiết. Một phương thức quan trọng khác khiến chúng ta hứng khởi là find
, nó sẽ lấy về những giá trị dựa trên thông tin được cung cấp qua các tham số mà phương thức truyền vào.
Vậy đó là quá trình triển khai của driver cho MongoDB, và tôi đã cố gắng tóm gọn nó.
Thiết lập User Model
Tuân thủ các tiêu chuẩn của hệ thống xác thực, chúng ta cần triển khai User Model, nó phải triển khai contract Illuminate\Contracts\Auth\Authenticatable
.
Tiếp tục và tạo một file app/Models/Auth/User.php
với nội dung dưới đây:
010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
<?php// app/Models/Auth/User.phpnamespace
App\Models\Auth;
use
Illuminate\Contracts\Auth\Authenticatable
as
AuthenticatableContract;use
App\Services\Contracts\NosqlServiceInterface;
class
User
implements
AuthenticatableContract{ private
$conn;
private
$username; private
$password; protected
$rememberTokenName
=
'remember_token';
public
function
__construct(NosqlServiceInterface
$conn) { $this->conn =
$conn; }
/** * Fetch user by Credentials * * @param array $credentials * @return Illuminate\Contracts\Auth\Authenticatable */ public
function
fetchUserByCredentials(Array
$credentials) { $arr_user
=
$this->conn->find('users', ['username'
=>
$credentials['username']]);
if
(!
is_null($arr_user)) { $this->username =
$arr_user['username']; $this->password =
$arr_user['password']; }
return
$this; }
/** * {@inheritDoc} * @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifierName() */ public
function
getAuthIdentifierName() { return
"username"; }
/** * {@inheritDoc} * @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifier() */ public
function
getAuthIdentifier() { return
$this->{$this->getAuthIdentifierName()}; }
/** * {@inheritDoc} * @see \Illuminate\Contracts\Auth\Authenticatable::getAuthPassword() */ public
function
getAuthPassword() { return
$this->password; }
/** * {@inheritDoc} * @see \Illuminate\Contracts\Auth\Authenticatable::getRememberToken() */ public
function
getRememberToken() { if
(!
empty($this->getRememberTokenName())) { return
$this->{$this->getRememberTokenName()}; } }
/** * {@inheritDoc} * @see \Illuminate\Contracts\Auth\Authenticatable::setRememberToken() */ public
function
setRememberToken($value) { if
(!
empty($this->getRememberTokenName())) { $this->{$this->getRememberTokenName()} =
$value; } }
/** * {@inheritDoc} * @see \Illuminate\Contracts\Auth\Authenticatable::getRememberTokenName() */ public
function
getRememberTokenName() { return
$this->rememberTokenName; }}
Bạn lẽ ra nên chú ý rằng App\Models\Auth\User
đã implement contract Illuminate\Contracts\Auth\Authenticatable.
Đa số các phương thức đã implement class của chúng ta đã tự giải thích. Dù nói như vậy, chúng ta đã định nghĩa phương thức fetchUserByCredentials
, nó lấy ra người dùng từ back-end. Trong trường hợp của chúng ta, nó là class MongoDatabase
sẽ được gọi để trả về thông tin cần thiết.
Đó là phần triển khai của User Model.
Thiết lập Provider xác thực
Như chúng ta đã thảo luận trước đó, hệ thống xác thực của Laravel gồm có 2 thành phần - guards và providers.
Trong phần này, chúng ta sẽ tạo provider xác thực để xử lý phần lấy người dùng từ back-end.
Tiếp đến tạo một file app/Extensions/MongoUserProvider.php
như hiển thị bên dưới.
0102030405060708091011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
<?php// app/Extensions/MongoUserProvider.phpnamespace
App\Extensions;
use
Illuminate\Support\Str;use
Illuminate\Contracts\Auth\UserProvider;use
Illuminate\Contracts\Auth\Authenticatable;
class
MongoUserProvider
implements
UserProvider{ /** * The Mongo User Model */ private
$model;
/** * Create a new mongo user provider. * * @return \Illuminate\Contracts\Auth\Authenticatable|null * @return void */ public
function
__construct(\App\Models\Auth\User
$userModel) { $this->model =
$userModel; }
/** * Retrieve a user by the given credentials. * * @param array $credentials * @return \Illuminate\Contracts\Auth\Authenticatable|null */ public
function
retrieveByCredentials(array
$credentials) { if
(empty($credentials)) { return; }
$user
=
$this->model->fetchUserByCredentials(['username'
=>
$credentials['username']]);
return
$user; }
/** * Validate a user against the given credentials. * * @param \Illuminate\Contracts\Auth\Authenticatable $user * @param array $credentials Request credentials * @return bool */ public
function
validateCredentials(Authenticatable
$user, Array
$credentials) { return
($credentials['username'] ==
$user->getAuthIdentifier() && md5($credentials['password']) ==
$user->getAuthPassword()); }
public
function
retrieveById($identifier) {}
public
function
retrieveByToken($identifier,
$token) {}
public
function
updateRememberToken(Authenticatable
$user,
$token) {}}
Lần nữa bạn cần chắc rằng provider tự biên phải implement contract Illuminate\Contracts\Auth\UserProvider.
Tiếp tục, định nghĩa 2 phương thức quan trọng - retrieveByCredentials vả validateCredentials.
Phương thức retrieveByCredentials
đươc dùng để lấy thông tin người bằng class User model đã được đề cập trước đó. Mặt khác, phương thức validateCredentials
được dùng để xác minh một người dùng với các thông tin đã cung cấp.
Và đó là phần triển khai của provider cho xác thực tự biên của chúng ta. Trong phần tiếp đến, chúng ta sẽ tiếp tục tạo ra một guard để tương tác với provider xác thực MongoUserProvider.
Thiết lập guard xác thực
Nhưng đã thảo luận trước đó, guard trong hệ thống xác thực của Laravel quy định cách user được xác minh thế nào. Trong trường hợp này, chúng ta sẽ kiểm tra sự tồn tại của tham số jsondata trong request, nó nên chứa chuỗi JSON được mã hoá của các thông tin.
Trong phần này, chúng ta sẽ tạo một guard tương tác với provider xác thực vừa được tạo ra trong phần trước đó.
Tiếp tục tạo một file app/Services/Auth/JsonGuard.php
với nội dung sau đây:
001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123
<?php// app/Services/Auth/JsonGuard.phpnamespace
App\Services\Auth;
use
Illuminate\Http\Request;use
Illuminate\Contracts\Auth\Guard;use
Illuminate\Contracts\Auth\UserProvider;use
GuzzleHttp\json_decode;use
phpDocumentor\Reflection\Types\Array_;use
Illuminate\Contracts\Auth\Authenticatable;
class
JsonGuard
implements
Guard{ protected
$request; protected
$provider; protected
$user;
/** * Create a new authentication guard. * * @param \Illuminate\Contracts\Auth\UserProvider $provider * @param \Illuminate\Http\Request $request * @return void */ public
function
__construct(UserProvider
$provider, Request
$request) { $this->request =
$request; $this->provider =
$provider; $this->user = NULL; }
/** * Determine if the current user is authenticated. * * @return bool */ public
function
check() { return
!
is_null($this->user()); }
/** * Determine if the current user is a guest. * * @return bool */ public
function
guest() { return
!
$this->check(); }
/** * Get the currently authenticated user. * * @return \Illuminate\Contracts\Auth\Authenticatable|null */ public
function
user() { if
(!
is_null($this->user)) { return
$this->user; } }
/** * Get the JSON params from the current request * * @return string */ public
function
getJsonParams() { $jsondata
=
$this->request->query('jsondata');
return
(!empty($jsondata) ? json_decode($jsondata, TRUE) : NULL); }
/** * Get the ID for the currently authenticated user. * * @return string|null */ public
function
id() { if
($user
=
$this->user()) { return
$this->user()->getAuthIdentifier(); } }
/** * Validate a user's credentials. * * @return bool */ public
function
validate(Array
$credentials=[]) { if
(empty($credentials['username']) ||
empty($credentials['password'])) { if
(!$credentials=$this->getJsonParams()) { return
false; } }
$user
=
$this->provider->retrieveByCredentials($credentials);
if
(!
is_null($user) &&
$this->provider->validateCredentials($user,
$credentials)) { $this->setUser($user);
return
true; }
else
{ return
false; } }
/** * Set the current user. * * @param Array $user User info * @return void */ public
function
setUser(Authenticatable
$user) { $this->user =
$user; return
$this; }}
Trước hết, class của ta cần implement interface Illuminate\Contracts\Auth\Guard
. Do đó, chúng ta cần định nghĩa tất cả các phương thức trong interface đó.
Điều quan trọng cần chú ý là hàm __construc
t yêu cầu một triển khai của Illuminate\Contracts\Auth\UserProvider
. Trong trường hợp này, chúng ta sẽ chuyển vào một instance của App\Extensions\MongoUserProvider
, chúng ta sẽ thấy trong phần sau đó:
Tiếp theo, một hàm getJsonParams
lấy thông tin người dùng từ các tham số của request tên là jsondata
. Như mong đợi chúng ta sẽ nhận một chuỗi JSON được mã hoá của thông tin người dùng, chúng ta sẽ dùng hàm json_decode
để giải mã dữ liệu JSON.
Trong hàm validate, điều đầu tiên chúng ta kiểm tra là sự tồn tại của tham số $credentials
. Nếu nó không hiện diện, chúng ta gọi phương thức getJsonParams
để lấy thông tin người dùng từ các tham số trong request.
Tiếp theo, chúng tôi gọi phương thức retrieveByCredentials
của provider MongoUserProvider
để lấy người dùng từ database MongoDB ở back-end. Cuối cùng, là phương thức validateCredentials
của provider MongoUserProvide
r để kiểm tra tính hợp lệ của User.
Vậy đó là phần triển khai của guard tự biên của chúng ta. Phần tiếp theo mô tả cách kết nối những mảnh ghép lại để tạo thành một hệ thống xác thực hoàn chỉnh.
Kết nối mọi cùng nhau
Cho đến giờ, chúng ta đã phát triển tất cả các yếu tố của guard xác thực, nó sẽ cung cấp cho ta một hệ thống xác thực mới. Tuy nhiên, nó sẽ không hoạt động ngay tức thì vì chúng ta cần phải đăng ký lần đầu bằng việc ràng buộc với Laravel service container.
Như bạn đã biết, Laravel service provider là một nơi để triển khai những ràng buộc cần thiết.
Tiếp tục mở file app/Providers/AuthServiceProvider.php
để bổ sung ràng buộc xác thực cho service container. Nếu nó chưa có bất kỳ thay đổi nào, bạn có thể thay thế nó với nội dung sau đây:
01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
<?php// app/Providers/AuthServiceProvider.phpnamespace
App\Providers;
use
Illuminate\Support\Facades\Auth;use
Illuminate\Support\Facades\Gate;use
Illuminate\Foundation\Support\Providers\AuthServiceProvider
as
ServiceProvider;use
App\Services\Auth\JsonGuard;use
App\Extensions\MongoUserProvider;use
App\Database\MongoDatabase;use
App\Models\Auth\User;use
Illuminate\Http\Request;use
Illuminate\Support\Facades\Config;
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();
$this->app->bind('App\Database\MongoDatabase',
function
($app) { return
new
MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database')); });
$this->app->bind('App\Models\Auth\User',
function
($app) { return
new
User($app->make('App\Database\MongoDatabase')); });
// add custom guard provider Auth::provider('mongo',
function
($app,
array
$config) { return
new
MongoUserProvider($app->make('App\Models\Auth\User')); });
// add custom guard Auth::extend('json',
function
($app,
$name,
array
$config) { return
new
JsonGuard(Auth::createUserProvider($config['provider']),
$app->make('request')); }); }
public
function
register() { $this->app->bind( 'App\Services\Contracts\NosqlServiceInterface', 'App\Database\MongoDatabase' ); }}
Hãy xem kỹ phương thức boot
, nó chứa các ràng buộc của provider.
Để bắt đầu, chúng ta sẽ tạo thông tin ràng buộc cho các thành phần App\Database\MongoDatabase
và App\Models\Auth\User.
1234567
$this->app->bind('App\Database\MongoDatabase',
function
($app) { return
new
MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database'));});
$this->app->bind('App\Models\Auth\User',
function
($app) { return
new
User($app->make('App\Database\MongoDatabase'));});
Đã được một lúc chúng ta nói về provider và guard, và đây là lúc để gắng guard của chúng ta vào hệ thống xác thực của Laravel.
Chúng ta đã dùng phương thức của provider của Facde Auth
để bổ sung provider xác thực tự biên bên dưới key mongo. Nhắc lại rằng key này dùng cho xác lập trước đó đã bổ sung trong file auth.php.
123
Auth::provider('mongo',
function
($app,
array
$config) { return
new
MongoUserProvider($app->make('App\Models\Auth\User'));});
Tương tự cách này, chúng ta sẽ chén triển khai cho guard của chúng ta bằng cách dùng phương thức extend của facade Auth
.
123
Auth::extend('json',
function
($app,
$name,
array
$config) { return
new
JsonGuard(Auth::createUserProvider($config['provider']),
$app->make('request'));});
Tiếp theo, có một phương thức register
mà ta đã dùng để gắn kết interface App\Services\Contracts\NosqlServiceInterface
đến triển khai App\Database\MongoDatabase.
1234
$this->app->bind( 'App\Services\Contracts\NosqlServiceInterface', 'App\Database\MongoDatabase');
Vậy bất cứ khi nào có nhu cầu giải quyết dependency App\Services\Contracts\NosqlServiceInterface
, Laravel trả lời với triển khai của adapter App\Database\MongoDatabase.
Lợi ích của cách tiếp cận này là có thể dễ dàng thay đổi phần triển khai đã có với một phần triển khai khác. Ví dụ ai đó muốn thay thế triển khai App\Database\MongoDatabase
bằng adapter CouchDB trong tương lai. Trong trường hợp đó, họ chỉ cần bổ sung phần kết nối tương tứng trong phương thức register.
Vậy đó là service provider cho cách sắp xếp của bạn. Ở thời điểm này, chúng ta có mọi thứ cần cho để kiểm tra phần triển khai guard tự biên của chúng ta, vậy tiếp theo là những phần nói về việc kiểm tra này.
Nó có hoạt động không?
Bạn đã thực hiện xong những phần khó khăn khi thiết lập guard xác thực tự biên đầu tiên của chúng ta, và giờ là lúc thâu được những ích lợi khi chúng ta sẽ tiếp tục và thử xem sao.
Hãy nhanh chóng triển khai một file controller cơ bản app/Http/Controllers/MongoController.php
như bên dưới đây.
010203040506070809101112131415161718192021
<?php// app/Http/Controllers/MongoController.phpnamespace
App\Http\Controllers;
use
App\Http\Controllers\Controller;use
Illuminate\Contracts\Auth\Guard;
class
MongoController
extends
Controller{ public
function
login(Guard
$auth_guard) { if
($auth_guard->validate()) { // get the current authenticated user $user
=
$auth_guard->user();
echo
'Success!'; }
else
{ echo
'Not authorized to access this page!'; } }}
Nhìn kỹ vào phần phụ thuộc của phương thức login, nó yêu cầu triển khai của guard Illuminate\Contracts\Auth\Guard
. Khi chúng ta thiết lập guard tự biên là guard mặc định trong file auth.php
, thực tế là App\Services\Auth\JsonGuard
sẽ được đưa vào!
Tiếp đến, chúng ta gọi phương thức validate
của class App\Services\Auth\JsonGuard
, nó sẽ chuyển thành một loạt việc gọi các phương thức:
Nó gọi phương thức
retrieveByCredentials
của classApp\Extensions\MongoUserProvider.
Phương thức
retrieveByCredentials
gọi phương thứcfetchUserByCredentials
của classApp\Models\Auth\User.
Phương thức
fetchUserByCredentials
gọi phương thứcfind
củaApp\Database\MongoDatabase
để lấy thông tin người dùng.Cuối cùng, phương thức
find
củaApp\Database\MongoDatabase
trả về phản hồi!
Nếu mọi thứ hoạt động như mong đợi, chúng ta sẽ có một người dùng đã được xác thực bằng cách gọi phương thức user
của guard của chúng ta.
Để truy xuất controller, bạn nên bổ sung một route trong file routes/web.php.
1
Route::get('/custom/mongo/login',
'MongoController@login');
Hãy thử truy cập URL http://your-laravel-site/custom/mongo/login mà không cần truyền bất kỳ tham số nào và bạn sẽ thấy thông báo "not authorized".
Mặt khác, hãy thử một cái gì đó như http://your-laravel-site/ custom/mongo/login?Jsondata={"username": "admin", "password": "admin"} và nó sẽ trả về một thông báo thành công nếu người dùng hiện hữu trong database của bạn.
Xin lưu ý rằng đây chỉ là cho ví dụ với mục đích chứng minh cách phần guard tự biên hoạt động thế nào. Bạn nên triển khai một giải pháp an toàn hơn cho tính năng như đăng nhập. Trong thực tế, tôi chỉ vừa cung cấp một cái nhìn về quy trình xác thực; bạn có trách nhiệm xây dựng một giải pháp an toàn và mạnh mẽ cho ứng dụng của bạn.
Kết thúc hành trình của chúng ta hôm nay, và hy vọng tôi sẽ trở lại với nhiều điều hữu ích hơn. Nếu bạn muốn tôi viết về một chủ đề cụ thể, đừng quên nhắn tin cho tôi nhé!
Tổng kết
Bản thân Laravel cung cấp một hệ thống xác thực vững chắc, nó có thể được mở rộng nếu bạn muốn triển khai một bản tự xây dựng. Đó là chủ đề ngày hôm nay để xây dựng một guard tự biên và đưa nó vào quy trình xác thực của Laravel.
Trong quá trình đó, chúng tôi đã tiến bước và phát triển một hệ thống xác thực người dùng dựa trên JSON trong yêu cầu và khớp nó với database MongoDB. Và để đạt được điều đó, chúng tôi đã tạo ra một guard tự xây dựng và triển khai một provider tự dựng.
Tôi hy vọng bài tập đã cung cấp cho bạn sự thấu hiểu về quá trình xác thực của Laravel, và bạn nên cảm thấy tự tin hơn về những tác vụ trong đó.
Dành cho những ai vừa bắt đầu với Laravel hoặc tìm kiếm để mở rộng kiến thức của bạn, website hoặc ứng dụng với những phần mở rộng, chúng tôi có nhiều thứ đa dạng bạn có thể học trên Envato Market.
Last updated