Indonesian (Bahasa Indonesia) translation by Imam Firmansyah (you can also view the original English article)
Pada artikel ini, kita akan membahas sistem otentikasi pada framework Laravel. Tujuan utama dari artikel ini adalah untuk menciptakan Custom Authentication Guard dengan memperluas core dari sistem otentikasi.
Laravel menyediakan sistem otentikasi yang sangat solid dalam core sistemnya yang membuat implementasi otentikasi dasar menjadi mudah. Sebenarnya, Anda hanya perlu menjalankan beberapa perintah untuk menyiapkan rangka sistem autentikasi.
Selain itu, sistem ini sendiri dirancang sedemikian rupa sehingga Anda bisa mengembangkan dan memasang adaptor otentikasi kustom Anda juga. Itulah yang akan kita bahas secara rinci di seluruh artikel ini. Sebelum kita langsung ke tahap implementasi, kita akan mulai dengan diskusi tentang elemen dasar di sistem pengaman dan penyedia sistem otentikasi Laravel.
Element Utama: Guards dan Providers
Sistem otentikasi Laravel terdiri dari dua elemen yaitu core-guards dan providers.
Guards
Anda bisa menganalogikan guards sebagai cara untuk memasok logika yang digunakan untuk mengidentifikasi pengguna yang diotentikasi. Intinya, Laravel menyediakan guards yang berbeda seperti session dan token. Session Guards menjaga status pengguna di setiap permintaan pada cookies, dan di sisi lain Token Guards mengotentikasi pengguna dengan memeriksa token yang valid pada setiap permintaan.
Jadi, seperti yang Anda ketahui, guards mendefinisikan logika otentikasi, dan hal itu tidak selalu berhubungan dengan mengambil identitas yang valid dari back end. Anda dapat menerapkan guards yang hanya memeriksa keberadaan hal tertentu pada saat permintaan header dan mengotentikasi pengguna berdasarkan hal tersebut.
Kemudian, kita juga akan menerapkan guards yang memeriksa parameter JSON tertentu pada permintaan header dan mengambil data valid user dari back-end MongoDB.
Providers
Jika guards mendefinisikan logika otentikasi, authentication provider bertanggung jawab untuk mengambil data pengguna dari penyimpanan back-end. Jika guards memerlukan pengguna untuk divalidasi terhadap penyimpanan back-end maka penerapan pengambilan data user masuk ke authentication provider.
Laravel mengirimkan melalui dua authentication provider bawaan, yaitu: Database dan Eloquent. Database menangani pengambilan data identitas pengguna secara langsung dari penyimpanan back-end, sementara Eloquent menyediakan lapisan abstraksi yang diperlukan.
Dalam contoh yang diberikan, kita akan menerapkan otentikasi provider MongoDB yang mengambil data identitas pengguna dari back-end MongoDB.
Jadi itu adalah pengantar dasar dari guards dan providers sistem otentikasi Laravel. Dari bagian berikutnya dan seterusnya, kita akan fokus pada pengembangan custom authentication guard and provider!
Sekilas untuk File Setup
Mari kita lihat sekilas daftar file yang akan kita terapkan sepanjang artikel ini.
-
config/auth.php
: Ini adalah file konfigurasi otentikasi dimana kita akan menambahkan entri dari custom guard kita. -
config/mongo.php
: Ini adalah file yang menyimpan konfigurasi MongoDB. -
app/Services/Contracts/NosqlServiceInterface.php
: Ini adalah file konfigurasi dimana antarmuka yang akan diterapkan pada database class Mongo kustom yang akan dibuat. -
app/Database/MongoDatabase.php
: Ini adalah file konfigurasi database class utama pada MongoDB. -
app/Models/Auth/User.php
: Ini adalah file konfigurasi user model class yang menerapkan aturan otentikasi. -
app/Extensions/MongoUserProvider.php
: Ini adalah file konfigurasi yang berisi penerapan dari authentication provider. -
app/Services/Auth/JsonGuard.php
: Ini adalah file konfigurasi yang berisi penerapan dari authentication guard driver. -
app/Providers/AuthServiceProvider.php
: Ini adalah file yang akan kita gunakan untuk menambahkan service container bindings kita. -
app/Http/Controllers/MongoController.php
: Ini adalah file pengontrol demo yang akan kita terapkan untuk menguji guards kustom.
Jangan khawatir jika daftar file membingungkan karena kita akan membahas semuanya secara rinci saat kita mengimplementasikannya.
Deep Dive Ke dalam Implementasi
Pada bagian ini, kita akan mengimplementasikan file-file yang diperlukan.
Hal pertama yang perlu kita lakukan adalah menginformasikan kepada Laravel tentang custom guard kita. Silakan lihat dan masukkan rincian kustom guards seperti di file config/auth.php
yang ditunjukkan .
1 |
...
|
2 |
...
|
3 |
'guards' => [ |
4 |
'web' => [ |
5 |
'driver' => 'session', |
6 |
'provider' => 'users', |
7 |
],
|
8 |
|
9 |
'api' => [ |
10 |
'driver' => 'token', |
11 |
'provider' => 'users', |
12 |
],
|
13 |
|
14 |
'custom' => [ |
15 |
'driver' => 'json', |
16 |
'provider' => 'mongo', |
17 |
],
|
18 |
],
|
19 |
...
|
20 |
...
|
Seperti yang Anda lihat, kita telah menambahkan custom guard pada custom key.
Selanjutnya, kita perlu untuk menambahkan kumpulan provider pada bagian providers.
1 |
...
|
2 |
...
|
3 |
'providers' => [ |
4 |
'users' => [ |
5 |
'driver' => 'eloquent', |
6 |
'model' => App\User::class, |
7 |
],
|
8 |
'mongo' => [ |
9 |
'driver' => 'mongo' |
10 |
],
|
11 |
|
12 |
// 'users' => [
|
13 |
// 'driver' => 'database',
|
14 |
// 'table' => 'users',
|
15 |
// ],
|
16 |
],
|
17 |
...
|
18 |
...
|
Kita telah menambahkan provider kita pada mongo key.
Terakhir, ubah nilai otentikasi guard bawaan dari web menjadi custom.
1 |
...
|
2 |
...
|
3 |
'defaults' => [ |
4 |
'guard' => 'custom', |
5 |
'passwords' => 'users', |
6 |
],
|
7 |
...
|
8 |
...
|
Tentu saja, itu belum akan berjalan, karena kita belum menerapkan file yang diperlukan. Dan itulah yang akan kita bahas dalam beberapa bagian berikutnya.
Menyiapkan MongoDB Driver
Pada bagian ini, kita akan menerapkan file-file yang mendasari instance MongoDB
Pertama, kita buat sebuah file konfigurasi config/mongo.php
yang menyimpan pengaturan koneksi bawaan MongoDB.
1 |
<?php
|
2 |
return [ |
3 |
'defaults' => [ |
4 |
'host' => '{HOST_IP}', |
5 |
'port' => '{HOST_PORT}', |
6 |
'database' => '{DB_NAME}' |
7 |
]
|
8 |
];
|
Tentu saja, Anda perlu mengganti nilai placeholder sesuai keinginan anda.
Alih-alih langsung menciptakan class yang berinteraksi dengan MongoDB, kita akan membuat sebuah antarmuka terlebih dahulu.
Manfaat membuat antarmuka adalah menyediakan aturan yang harus dipatuhi oleh developer saat menerapkannya. Selain itu, implementasi MongoDB kita dapat dengan mudah ditukar dengan implementasi NoSQL lainnya jika diperlukan.
Lanjutkan dengan membuat file antarmuka app/Services/Contracts/NosqlServiceInterface.php
dengan isi sebagai berikut.
1 |
<?php
|
2 |
// app/Services/Contracts/NosqlServiceInterface.php
|
3 |
namespace App\Services\Contracts; |
4 |
|
5 |
Interface NosqlServiceInterface |
6 |
{
|
7 |
/**
|
8 |
* Create a Document
|
9 |
*
|
10 |
* @param string $collection Collection/Table Name
|
11 |
* @param array $document Document
|
12 |
* @return boolean
|
13 |
*/
|
14 |
public function create($collection, Array $document); |
15 |
|
16 |
/**
|
17 |
* Update a Document
|
18 |
*
|
19 |
* @param string $collection Collection/Table Name
|
20 |
* @param mix $id Primary Id
|
21 |
* @param array $document Document
|
22 |
* @return boolean
|
23 |
*/
|
24 |
public function update($collection, $id, Array $document); |
25 |
|
26 |
/**
|
27 |
* Delete a Document
|
28 |
*
|
29 |
* @param string $collection Collection/Table Name
|
30 |
* @param mix $id Primary Id
|
31 |
* @return boolean
|
32 |
*/
|
33 |
public function delete($collection, $id); |
34 |
|
35 |
/**
|
36 |
* Search Document(s)
|
37 |
*
|
38 |
* @param string $collection Collection/Table Name
|
39 |
* @param array $criteria Key-value criteria
|
40 |
* @return array
|
41 |
*/
|
42 |
public function find($collection, Array $criteria); |
43 |
}
|
Ini adalah antarmuka yang cukup sederhana yang menyatakan metode dasar CRUD yang harus didefinisikan oleh class yang mengimplementasikan antarmuka ini.
Sekarang, kita akan mendefinisikan class pada app/Database/MongoDatabase.php
.
1 |
<?php
|
2 |
// app/Database/MongoDatabase.php
|
3 |
namespace App\Database; |
4 |
|
5 |
use App\Services\Contracts\NosqlServiceInterface; |
6 |
|
7 |
class MongoDatabase implements NosqlServiceInterface |
8 |
{
|
9 |
private $connection; |
10 |
private $database; |
11 |
|
12 |
public function __construct($host, $port, $database) |
13 |
{
|
14 |
$this->connection = new MongoClient( "mongodb://{$host}:{$port}" ); |
15 |
$this->database = $this->connection->{$database}; |
16 |
}
|
17 |
|
18 |
/**
|
19 |
* @see \App\Services\Contracts\NosqlServiceInterface::find()
|
20 |
*/
|
21 |
public function find($collection, Array $criteria) |
22 |
{
|
23 |
return $this->database->{$collection}->findOne($criteria); |
24 |
}
|
25 |
|
26 |
public function create($collection, Array $document) {} |
27 |
public function update($collection, $id, Array $document) {} |
28 |
public function delete($collection, $id) {} |
29 |
}
|
Tentu saja, saya berasumsi bahwa Anda telah menginstal MongoDB dan ekstensi PHP MongoDB yang sesuai.
method __construct
menginisiasikan class MongoClient
dengan parameter-parameter yang diperlukan. Metode penting lainnya yang kita perlukan adalah method find
, yang mengambil catatan berdasarkan kriteria yang diberikan sebagai method argumen.
Begitulah implementasi driver MongoDB, dan saya mencoba untuk membuatnya sesederhana mungkin.
Mengatur User Model
Dengan mengikuti standar sistem otentikasi, kita perlu menerapkan User Model yang harus menerapkan aturan Illuminate\Contracts\Auth\Authenticatable
.
Lalu, buat file app/Models/Auth/User.php
dengan isi sebagai berikut.
1 |
<?php
|
2 |
// app/Models/Auth/User.php
|
3 |
namespace App\Models\Auth; |
4 |
|
5 |
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; |
6 |
use App\Services\Contracts\NosqlServiceInterface; |
7 |
|
8 |
class User implements AuthenticatableContract |
9 |
{
|
10 |
private $conn; |
11 |
|
12 |
private $username; |
13 |
private $password; |
14 |
protected $rememberTokenName = 'remember_token'; |
15 |
|
16 |
public function __construct(NosqlServiceInterface $conn) |
17 |
{
|
18 |
$this->conn = $conn; |
19 |
}
|
20 |
|
21 |
/**
|
22 |
* Fetch user by Credentials
|
23 |
*
|
24 |
* @param array $credentials
|
25 |
* @return Illuminate\Contracts\Auth\Authenticatable
|
26 |
*/
|
27 |
public function fetchUserByCredentials(Array $credentials) |
28 |
{
|
29 |
$arr_user = $this->conn->find('users', ['username' => $credentials['username']]); |
30 |
|
31 |
if (! is_null($arr_user)) { |
32 |
$this->username = $arr_user['username']; |
33 |
$this->password = $arr_user['password']; |
34 |
}
|
35 |
|
36 |
return $this; |
37 |
}
|
38 |
|
39 |
/**
|
40 |
* {@inheritDoc}
|
41 |
* @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifierName()
|
42 |
*/
|
43 |
public function getAuthIdentifierName() |
44 |
{
|
45 |
return "username"; |
46 |
}
|
47 |
|
48 |
/**
|
49 |
* {@inheritDoc}
|
50 |
* @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifier()
|
51 |
*/
|
52 |
public function getAuthIdentifier() |
53 |
{
|
54 |
return $this->{$this->getAuthIdentifierName()}; |
55 |
}
|
56 |
|
57 |
/**
|
58 |
* {@inheritDoc}
|
59 |
* @see \Illuminate\Contracts\Auth\Authenticatable::getAuthPassword()
|
60 |
*/
|
61 |
public function getAuthPassword() |
62 |
{
|
63 |
return $this->password; |
64 |
}
|
65 |
|
66 |
/**
|
67 |
* {@inheritDoc}
|
68 |
* @see \Illuminate\Contracts\Auth\Authenticatable::getRememberToken()
|
69 |
*/
|
70 |
public function getRememberToken() |
71 |
{
|
72 |
if (! empty($this->getRememberTokenName())) { |
73 |
return $this->{$this->getRememberTokenName()}; |
74 |
}
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
* {@inheritDoc}
|
79 |
* @see \Illuminate\Contracts\Auth\Authenticatable::setRememberToken()
|
80 |
*/
|
81 |
public function setRememberToken($value) |
82 |
{
|
83 |
if (! empty($this->getRememberTokenName())) { |
84 |
$this->{$this->getRememberTokenName()} = $value; |
85 |
}
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
* {@inheritDoc}
|
90 |
* @see \Illuminate\Contracts\Auth\Authenticatable::getRememberTokenName()
|
91 |
*/
|
92 |
public function getRememberTokenName() |
93 |
{
|
94 |
return $this->rememberTokenName; |
95 |
}
|
96 |
}
|
Anda seharusnya sudah tahu bahwa App\Models\Auth\User
menerapkan aturan Illuminate\Contracts\Auth\Authenticatable
.
Sebagian besar metode yang diterapkan di class kita cukup jelas. Karena itu, kita sudah mendefinisikan method fetchUserByCredentials
, yang mengambil data pengguna dari back-end yang tersedia. Dalam hal ini, class MongoDatabase
yang akan dipanggil untuk mengambil informasi yang diperlukan.
Itulah implementasi dari user model.
Mengatur Authentication Provider
Seperti yang telah kita bahas sebelumnya, sistem otentikasi Laravel terdiri dari dua elemen - guards dan providers.
Pada bagian ini, kita akan membuat sebuah authentication provider yang menangani pengambilan data user dari back-end.
Buat file app/Extensions/MongoUserProvider.php
seperti berikut ini.
1 |
<?php
|
2 |
// app/Extensions/MongoUserProvider.php
|
3 |
namespace App\Extensions; |
4 |
|
5 |
use Illuminate\Support\Str; |
6 |
use Illuminate\Contracts\Auth\UserProvider; |
7 |
use Illuminate\Contracts\Auth\Authenticatable; |
8 |
|
9 |
class MongoUserProvider implements UserProvider |
10 |
{
|
11 |
/**
|
12 |
* The Mongo User Model
|
13 |
*/
|
14 |
private $model; |
15 |
|
16 |
/**
|
17 |
* Create a new mongo user provider.
|
18 |
*
|
19 |
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
20 |
* @return void
|
21 |
*/
|
22 |
public function __construct(\App\Models\Auth\User $userModel) |
23 |
{
|
24 |
$this->model = $userModel; |
25 |
}
|
26 |
|
27 |
/**
|
28 |
* Retrieve a user by the given credentials.
|
29 |
*
|
30 |
* @param array $credentials
|
31 |
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
32 |
*/
|
33 |
public function retrieveByCredentials(array $credentials) |
34 |
{
|
35 |
if (empty($credentials)) { |
36 |
return; |
37 |
}
|
38 |
|
39 |
$user = $this->model->fetchUserByCredentials(['username' => $credentials['username']]); |
40 |
|
41 |
return $user; |
42 |
}
|
43 |
|
44 |
/**
|
45 |
* Validate a user against the given credentials.
|
46 |
*
|
47 |
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
48 |
* @param array $credentials Request credentials
|
49 |
* @return bool
|
50 |
*/
|
51 |
public function validateCredentials(Authenticatable $user, Array $credentials) |
52 |
{
|
53 |
return ($credentials['username'] == $user->getAuthIdentifier() && |
54 |
md5($credentials['password']) == $user->getAuthPassword()); |
55 |
}
|
56 |
|
57 |
public function retrieveById($identifier) {} |
58 |
|
59 |
public function retrieveByToken($identifier, $token) {} |
60 |
|
61 |
public function updateRememberToken(Authenticatable $user, $token) {} |
62 |
}
|
Sekali lagi, Anda perlu memastikan bahwa custom provider harus menerapkan aturan Illuminate\Contracts\Auth\UserProvider
.
Kedepannya, ini mendefinisikan dua method penting — retrieveByCredentials dan validateCredentials.
Method retrieveByCredentials
method digunakan untuk mengambil data identitas pengguna menggunakan user model class yang telah dibahas di bagian sebelumnya. Di sisi lain, method validateCredentials
digunakan untuk memvalidasi pengguna terhadap sekumpulan identitas yang diberikan.
Itu adalah implementasi dari custom authentication provider kita. Pada bagian selanjutnya, kita akan membuat guards yang berinteraksi dengan authentication provider MongoUserProvider
.
Mengatur Authentication Guard
Seperti yang telah kita bahas sebelumnya, guard pada sistem otentikasi Laravel menentukan bagaimana pengguna diautentikasi. Dalam hal ini, kita akan memeriksa keberadaan permintaan parameter jsondata yang berisi identitas string pada JSON-encoded.
Pada bagian ini, kita akan membuat guard yang berinteraksi dengan authentication provider yang telah kita buat sebelumnya.
Buat file app/Services/Auth/JsonGuard.php
dengan isi sebagai berikut.
1 |
<?php
|
2 |
// app/Services/Auth/JsonGuard.php
|
3 |
namespace App\Services\Auth; |
4 |
|
5 |
use Illuminate\Http\Request; |
6 |
use Illuminate\Contracts\Auth\Guard; |
7 |
use Illuminate\Contracts\Auth\UserProvider; |
8 |
use GuzzleHttp\json_decode; |
9 |
use phpDocumentor\Reflection\Types\Array_; |
10 |
use Illuminate\Contracts\Auth\Authenticatable; |
11 |
|
12 |
class JsonGuard implements Guard |
13 |
{
|
14 |
protected $request; |
15 |
protected $provider; |
16 |
protected $user; |
17 |
|
18 |
/**
|
19 |
* Create a new authentication guard.
|
20 |
*
|
21 |
* @param \Illuminate\Contracts\Auth\UserProvider $provider
|
22 |
* @param \Illuminate\Http\Request $request
|
23 |
* @return void
|
24 |
*/
|
25 |
public function __construct(UserProvider $provider, Request $request) |
26 |
{
|
27 |
$this->request = $request; |
28 |
$this->provider = $provider; |
29 |
$this->user = NULL; |
30 |
}
|
31 |
|
32 |
/**
|
33 |
* Determine if the current user is authenticated.
|
34 |
*
|
35 |
* @return bool
|
36 |
*/
|
37 |
public function check() |
38 |
{
|
39 |
return ! is_null($this->user()); |
40 |
}
|
41 |
|
42 |
/**
|
43 |
* Determine if the current user is a guest.
|
44 |
*
|
45 |
* @return bool
|
46 |
*/
|
47 |
public function guest() |
48 |
{
|
49 |
return ! $this->check(); |
50 |
}
|
51 |
|
52 |
/**
|
53 |
* Get the currently authenticated user.
|
54 |
*
|
55 |
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
56 |
*/
|
57 |
public function user() |
58 |
{
|
59 |
if (! is_null($this->user)) { |
60 |
return $this->user; |
61 |
}
|
62 |
}
|
63 |
|
64 |
/**
|
65 |
* Get the JSON params from the current request
|
66 |
*
|
67 |
* @return string
|
68 |
*/
|
69 |
public function getJsonParams() |
70 |
{
|
71 |
$jsondata = $this->request->query('jsondata'); |
72 |
|
73 |
return (!empty($jsondata) ? json_decode($jsondata, TRUE) : NULL); |
74 |
}
|
75 |
|
76 |
/**
|
77 |
* Get the ID for the currently authenticated user.
|
78 |
*
|
79 |
* @return string|null
|
80 |
*/
|
81 |
public function id() |
82 |
{
|
83 |
if ($user = $this->user()) { |
84 |
return $this->user()->getAuthIdentifier(); |
85 |
}
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
* Validate a user's credentials.
|
90 |
*
|
91 |
* @return bool
|
92 |
*/
|
93 |
public function validate(Array $credentials=[]) |
94 |
{
|
95 |
if (empty($credentials['username']) || empty($credentials['password'])) { |
96 |
if (!$credentials=$this->getJsonParams()) { |
97 |
return false; |
98 |
}
|
99 |
}
|
100 |
|
101 |
$user = $this->provider->retrieveByCredentials($credentials); |
102 |
|
103 |
if (! is_null($user) && $this->provider->validateCredentials($user, $credentials)) { |
104 |
$this->setUser($user); |
105 |
|
106 |
return true; |
107 |
} else { |
108 |
return false; |
109 |
}
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
* Set the current user.
|
114 |
*
|
115 |
* @param Array $user User info
|
116 |
* @return void
|
117 |
*/
|
118 |
public function setUser(Authenticatable $user) |
119 |
{
|
120 |
$this->user = $user; |
121 |
return $this; |
122 |
}
|
123 |
}
|
Pertama, class kita perlu menerapkan interface Illuminate\Contracts\Auth\Guard
. Dengan demikian, kita perlu mendefinisikan semua method yang dideklarasikan di interface tersebut.
Hal penting yang perlu diingat disini adalah fungsi __construct
memerlukan penerapan dari Illuminate\Contracts\Auth\UserProvider
. Dalam hal ini, kita akan melewati contoh dari App\Extensions\MongoUserProvider
, yang akan kita bahas di bagian berikutnya.
Selanjutnya, terdapat fungsi getJsonParams
yang mengambil data identitas user dari permintaan parameter bernama jsondata
. Diharapkan bahwa kita akan menerima JSON-encoded string yang berisi identitas pengguna, kita telah menggunakan fungsi json_decode
untuk mendecode data JSON.
Pada fungsi validasi, hal yang harus dicek terlebih dahulu adalah argumen $credentials
. Jika tidak ada, kita akan memanggil method getJsonParams
untuk mengambil data identitas pengguna dari permintaan parameter.
Setelah itu, kita memanggil fungsi retrieveByCredentials
yang merupakan method dari provider MongoUserProvider
yang mengambil data pengguna dari database back-end MongoDB. Terakhir, yaitu validateCredentials
yang merupakan method dari provider MongoUserProvider
yang memeriksa validitas pengguna.
Itu adalah implementasi dari custom guard kita. Bagian selanjutnya menjelaskan bagaimana menyatukan potongan-potongan ini bersama-sama untuk membentuk sistem otentikasi yang berhasil.
Menggabungkan Semuanya
Sejauh ini, kita telah mengembangkan semua elemen dari custom authentication guard yang seharusnya memberi kita sistem autentikasi baru. Namun, tidak akan berhasil karena kita perlu mendaftarkannya terlebih dahulu menggunakan Laravel service container bindings.
Seperti yang Anda tahu, penyedia layanan Laravel adalah tempat yang tepat untuk menerapkan binding yang diperlukan.
Buka file app/Providers/AuthServiceProvider.php
yang mengizinkan kita untuk menambah otentikasi service container bindings. Jika tidak terdapat perubahan apapun, Anda bisa menggantinya dengan isi seperti berikut ini.
1 |
<?php
|
2 |
// app/Providers/AuthServiceProvider.php
|
3 |
namespace App\Providers; |
4 |
|
5 |
use Illuminate\Support\Facades\Auth; |
6 |
use Illuminate\Support\Facades\Gate; |
7 |
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; |
8 |
use App\Services\Auth\JsonGuard; |
9 |
use App\Extensions\MongoUserProvider; |
10 |
use App\Database\MongoDatabase; |
11 |
use App\Models\Auth\User; |
12 |
use Illuminate\Http\Request; |
13 |
use Illuminate\Support\Facades\Config; |
14 |
|
15 |
class AuthServiceProvider extends ServiceProvider |
16 |
{
|
17 |
/**
|
18 |
* The policy mappings for the application.
|
19 |
*
|
20 |
* @var array
|
21 |
*/
|
22 |
protected $policies = [ |
23 |
'App\Model' => 'App\Policies\ModelPolicy', |
24 |
];
|
25 |
|
26 |
/**
|
27 |
* Register any authentication / authorization services.
|
28 |
*
|
29 |
* @return void
|
30 |
*/
|
31 |
public function boot() |
32 |
{
|
33 |
$this->registerPolicies(); |
34 |
|
35 |
$this->app->bind('App\Database\MongoDatabase', function ($app) { |
36 |
return new MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database')); |
37 |
});
|
38 |
|
39 |
$this->app->bind('App\Models\Auth\User', function ($app) { |
40 |
return new User($app->make('App\Database\MongoDatabase')); |
41 |
});
|
42 |
|
43 |
// add custom guard provider
|
44 |
Auth::provider('mongo', function ($app, array $config) { |
45 |
return new MongoUserProvider($app->make('App\Models\Auth\User')); |
46 |
});
|
47 |
|
48 |
// add custom guard
|
49 |
Auth::extend('json', function ($app, $name, array $config) { |
50 |
return new JsonGuard(Auth::createUserProvider($config['provider']), $app->make('request')); |
51 |
});
|
52 |
}
|
53 |
|
54 |
public function register() |
55 |
{
|
56 |
$this->app->bind( |
57 |
'App\Services\Contracts\NosqlServiceInterface', |
58 |
'App\Database\MongoDatabase'
|
59 |
);
|
60 |
}
|
61 |
}
|
Mari kita gunakan method boot
yang berisi sebagian besar provider bindings.
Untuk memulainya, kita akan membuat binding untuk App\Database\MongoDatabase
dan elemen App\Models\Auth\User
.
1 |
$this->app->bind('App\Database\MongoDatabase', function ($app) { |
2 |
return new MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database')); |
3 |
});
|
4 |
|
5 |
$this->app->bind('App\Models\Auth\User', function ($app) { |
6 |
return new User($app->make('App\Database\MongoDatabase')); |
7 |
});
|
Sudah lama kita membicarakan provider dan guard, dan sekarang saatnya untuk memasukkan custom guard kita ke dalam sistem otentikasi Laravel.
kita telah menggunakan method provider dari Auth
untuk menambah custom authentication provider kita pada mongo. Perlu diingat bahwa key tersebut merupakan pengaturan yang ditambahkan sebelumnya di file auth.php
.
1 |
Auth::provider('mongo', function ($app, array $config) { |
2 |
return new MongoUserProvider($app->make('App\Models\Auth\User')); |
3 |
});
|
Dengan cara yang sama, kami akan menyisipkan implementasi custom guardi menggunakan metode extend Auth
facade.
1 |
Auth::extend('json', function ($app, $name, array $config) { |
2 |
return new JsonGuard(Auth::createUserProvider($config['provider']), $app->make('request')); |
3 |
});
|
Selanjutnya, ada metode register
bahwa kami telah digunakan untuk mengikat interface App\Services\Contracts\NosqlServiceInterface
ke implementasi App\Database\MongoDatabase
.
1 |
$this->app->bind( |
2 |
'App\Services\Contracts\NosqlServiceInterface', |
3 |
'App\Database\MongoDatabase'
|
4 |
);
|
Jadi kapanpun kita butuh untuk menyelesaikan dependensi App\Services\Contracts\NosqlServiceInterface
, Laravel merespon dengan penerapan dari adapter App\Database\MongoDatabase
.
Manfaat menggunakan pendekatan ini adalah dengan mudah bisa menukar implementasi yang diberikan dengan implementasi kustom. Misalnya, misalkan seseorang ingin mengganti implementasi App\Database\MongoDatabase
dengan CouchDB adapter. Dalam hal itu, In that case, mereka hanya perlu menambahkan binding yang sesuai dengan method register.
Jadi, itulah penyedia layanan yang Anda inginkan. Pada saat ini, kita memiliki semua yang diperlukan untuk menguji implementasi custom guard kita, jadi bagian berikutnya dan penutup adalah semua hal tentang itu.
Apakah Itu Bekerja?
Anda telah melakukan semua kerja keras untuk menyiapkan custom authentication guard pertama Anda, dan sekarang saatnya untuk menuai keuntungan seperti yang akan kita lakukan selanjutnya dan cobalah.
Mari kita implementasikan file controller dasar dengan cepat app/Http/Controllers/MongoController.php
seperti yang ditunjukkan dibawah ini.
1 |
<?php
|
2 |
// app/Http/Controllers/MongoController.php
|
3 |
namespace App\Http\Controllers; |
4 |
|
5 |
use App\Http\Controllers\Controller; |
6 |
use Illuminate\Contracts\Auth\Guard; |
7 |
|
8 |
class MongoController extends Controller |
9 |
{
|
10 |
public function login(Guard $auth_guard) |
11 |
{
|
12 |
if ($auth_guard->validate()) { |
13 |
// get the current authenticated user
|
14 |
$user = $auth_guard->user(); |
15 |
|
16 |
echo 'Success!'; |
17 |
} else { |
18 |
echo 'Not authorized to access this page!'; |
19 |
}
|
20 |
}
|
21 |
}
|
Perhatikan baik-baik dependency pada method login, yang memerlukan implementasi guard Illuminate\Contracts\Auth\Guard
. Karena kita telah mengatur custom guard kita sebagai guard default pada file auth.php
, yang akan disisipkan pada App\Services\Auth\JsonGuard
Kemudian, kita panggil fungsi validate
pada class App\Services\Auth\JsonGuard
, yang pada gilirannya memulai serangkaian pemanggilan method:
- Memanggil method
retrieveByCredentials
dari classApp\Extensions\MongoUserProvider
. - Method
retrieveByCredentials
memanggil methodfetchUserByCredentials
dari class penggunaApp\Models\Auth\User
. - Method
fetchUserByCredentials
memanggil methodfind
yang merupakan method dariApp\Database\MongoDatabase
untuk mengambil data identitas pengguna. - Terakhir, metod
find
yang merupakan method dariApp\Database\MongoDatabase
mengembalikan respon!
Jika semuanya bekerja seperti yang diharapkan, kita harus mendapatkan pengguna yang terautentikasi dengan memanggil method user
dari guard.
untuk mengakses controller, Anda perlu menambahkan rute pada file routes/web.php
.
1 |
Route::get('/custom/mongo/login', 'MongoController@login'); |
Cobalah mengakses alamat http://your-laravel-site/custom/mongo/login tanpa melewati parameter apapun dan Anda akan melihat pesan "not authorized".
Di sisi lain, cobalah mengakses http://your-laravel-site/custom/mongo/login?jsondata={"username":"admin","password":"admin"} dan itu akan menampilkan pesan sukses jika pengguna ada di database Anda.
Harap dicatat bahwa ini hanya untuk tujuan tertentu, untuk menunjukkan bagaimana authentication provider bekerja. Anda harus menerapkan solusi yang sangat mudah untuk fitur seperti login. Sebenarnya, saya baru saja memberikan wawasan tentang proses otentikasi; Anda bertanggung jawab untuk membangun solusi yang kuat dan aman untuk aplikasi Anda.
Itu mengakhiri perjalanan kita hari ini, dan mudah-mudahan saya akan kembali dengan hal-hal yang lebih bermanfaat lainnya. Jika Anda ingin saya menulis topik tertentu, jangan lupa memberitahu saya!
Kesimpulan
Framework LaravelThe Laravel framework menyediakan sistem otentikasi solid pada inti sistem yang bisa dikembangkan jika Anda ingin menerapkan yang custom. Itulah topik artikel hari ini untuk menerapkan authentication guard dan memasukkannya ke alur kerja otentikasi Laravel.
Dalam kursus tersebut, Kami terus mengembangkan sistem yang mengotentikasi pengguna berdasarkan muatan JSON sesuai permintaan dan mencocokkannya dengan database MongoDB. Dan untuk mencapainya, akhirnya kami menciptakan custom guard dan implementasi custom provider.
Saya harap latihan ini telah memberi Anda wawasan tentang aliran otentikasi Laravel, dan sekarang Anda seharusnya merasa lebih percaya diri.
Bagi Anda yang baru saja memulai dengan Laravel atau ingin memperluas pengetahuan, situs, atau aplikasi Anda dengan ekstensi, kami memiliki berbagai hal yang dapat Anda pelajari di Envato Market.
Saya ingin mendengar masukan dan saran Anda, jadi silahkan menggunakan feedback di bawah ini!