Posted on: July 04, 2023 09:51 PM
Posted by: Renato
Categories: Laravel jwt guard multiple_authen authentication
Views: 842
Multiple Authentication Guards for Laravel RESTful APIs (JWT)
Mas se você é relativamente novo no Laravel, múltiplas autenticações permitem que diferentes classes de usuários acessem partes diferentes/semelhantes do mesmo aplicativo.
JSON Web Tokens são um método RFC 7519 aberto e padrão do setor para representar reivindicações com segurança entre duas partes. [ para saber mais sobre jwt ]
O Laravel fornece uma maneira muito fácil e conveniente de criar APIs RESTful.
Hoje vou falar sobre como implementar vários guardas de autenticação ao usar APIs. Digamos que nosso sistema tenha 2 usuários: administrador e usuário. E temos 2 tabelas separadas para eles: admins e users. Faremos guardas para as 2 classes de usuários e restringiremos diferentes partes de nosso aplicativo com base nesses guardas.
Estou assumindo que você já criou o projeto Laravel e tudo mais configurado como configuração do banco de dados, scaffolding de autenticação, etc.
Estou usando tymon/jwt-auth para implementação de JWT.
Criando migração para administradores
run the following command:
php artisan make:migration create_admins_table
now from database/migrations we will edit as follow:
Migrate the database
run the following command:
php artisan migrate
Create Admin Model
run the following command:
php artisan make:model Admin
agora abra o arquivo de modelo em app/Admin.php e adicione o seguinte código:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class Admin extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* Guard for the model
*
* @var string
*/
protected $guard = 'admin';
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'admins';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
Add new Guard
Open config/auth.php file and make changes as follow:
<?php
.....
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
.....
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
'admin' => [
'driver' => 'jwt',
'provider' => 'admins',
],
],
..........
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
]
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
Create Login Function
Agora, para o login de demonstração, estou usando 2 funções diferentes em um controlador. Cabe a você como você deseja usá-lo. A parte principal é quando você chama o método try:
<?php
......
......
public function loginUser(Request $request) {
$credentials = $request->only('email', 'password');
try {
if (!$token = auth()->attempt($credentials)) {
return response()->json(['success' => false, 'error' => 'Some Error Message'], 401);
}
} catch (JWTException $e) {
return response()->json(['success' => false, 'error' => 'Failed to login, please try again.'], 500);
}
return $this->respondWithToken($token);
}
.....
public function loginAdmin(Request $request) {
$credentials = $request->only('email', 'password');
try {
if (!$token = auth()->guard('admin')->attempt($credentials)) {
return response()->json(['success' => false, 'error' => 'Some Error Message'], 401);
}
} catch (JWTException $e) {
return response()->json(['success' => false, 'error' => 'Failed to login, please try again.'], 500);
}
return $this->respondWithToken($token);
}
.....
/**
* Construct a json object to send to client
* @param string token
* @return Illuminate\Http\JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'success' => true,
'data' => [
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]
], 200);
}
......
......
lembre-se, api guard [config/auth.php] com usuários como provedor é definido como padrão, então não temos que encadear explicitamente o método guard, mas para admin, temos que encadear o método guard.
Configurando as rotas
adicione as seguintes rotas a routes/api.php :
<?php | |
..... | |
Route::middleware('auth:admin')->get('test/admin', function() { | |
return response()->json(['foo' => 'bar', 'user' => auth()->user()]); | |
}); | |
Route::middleware('auth:api')->get('test/user', function() { | |
return response()->json(['foo' => 'bar', 'user' => auth()->user()]); | |
}); | |
..... |
Lidar com a solicitação do usuário não autenticado
faça as seguintes alterações em app/Exceptions/Handler.php :
<?php | |
namespace App\Exceptions; | |
... | |
class Handler extends ExceptionHandler | |
{ | |
... | |
protected function unauthenticated($request, AuthenticationException $exception) | |
{ | |
return response()->json(['success' => false, 'error' => $exception->getMessage()], 401); | |
} | |
} |
Parabéns!! Nós terminamos de configurar tudo. adicione alguns usuários às duas tabelas, execute o seguinte comando:
php artisan serve
e teste essas APIs usando um cliente como o Postman.
Fontes?:
- multiple-authentication-guards-for-laravel-restful-apis-jwt-
Donate to Site
Renato
Developer