Posted on: January 04, 2022 10:22 AM
Posted by: Renato
Categories: Laravel webdev developer PHP programming
Views: 3637
Crie uma API autenticada JWT com Lumen
Neste tutorial, usaremos lúmen; uma microestrutura super rápida da laravel para construir uma API REST simples e segura. No final deste tutorial, você será capaz de construir APIs prontas para produção. Vamos começar!
Pré-requisito
- PHP >= 7.1.3
- OpenSSL PHP Extension
- PDO PHP Extension
- Mbstring PHP Extension
- Mysql >= 5.7
- Composer (Dependency Manager for PHP)
- Postman (To test your endpoints)
Instalação
Primeiro, você precisa obter o cli do lúmen.
$ composer global require "laravel/lumen-installer"
Se o download foi bem-sucedido, execute o comando abaixo para confirmar se o lúmen está instalado.
$ lumen
Agora execute este comando para criar o projeto lúmen
$ lumen new auth-app
Enter the project folder
$ cd auth-app
Run the app
$ php -S localhost:8000 -t public
Carregue o localhost: 8000 na barra de endereços do seu navegador e ele deve renderizar um resultado no navegador
Abra o projeto (auth-app) em seu editor preferido. * (VSCode)
Crie um arquivo .env, copie todo o conteúdo em .env.example para o arquivo .env e adicione suas configurações de banco de dados.
Em boostrap / app.php, descomente as fachadas e o método eloquente
//before
// $app->withFacades();
// $app->withEloquent();
//after
$app->withFacades();
$app->withEloquent();
Ativar com Facades injeta o aplicativo IoC em Illuminate \ Support \ Facades \ Facade. Sem fazer isso, mesmo se você estiver importando Illuminate \ Support \ Facades \ File, não funcionaria. Illuminate\Support\Facades\Facade. | Illuminate\Support\Facades\File
O método $ app-> withEloquent () também habilita o construtor de consultas. Ele está registrando o DatabaseServiceProvider, que é necessário para usar o construtor de consultas. Crédito.
Create a user
Faça a migração do banco de dados do usuário
$ php artisan make:migration create_users_table --create=users
Localize o arquivo de migração database/migrations /* _ create_users_table.php e adicione as colunas da tabela neede (nome, e-mail, senha); veja o código abaixo:
...
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique()->notNullable();
$table->string('password');
$table->timestamps();
});
}
...
Migrate your database
$ php artisan migrate
Adicionar rota de registro que como o nome indica; registrar usuários. Localize routes/web.php e insira o código necessário conforme visto abaixo
// API route group
$router->group(['prefix' => 'api'], function () use ($router) {
// Matches "/api/register
$router->post('register', 'AuthController@register');
});
Como vamos prefixar api em todos os nossos terminais, para reduzir a repetição, usaremos o agrupamento de rotas para fazer exatamente isso.
Este método ($ router-> post ($ uri, $ callback); recebe um $ url e um parâmetro $ callback. No $ callback, AuthController é nossa classe de controlador (criaremos essa classe em breve) e o registro é um método nessa classe.
Vamos criar nosso AuthControler.
Crie o arquivo app / Http / Controllers / AuthController.php e preencha-o com o código conforme mostrado abaixo.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class AuthController extends Controller
{
/**
* Store a new user.
*
* @param Request $request
* @return Response
*/
public function register(Request $request)
{
//validate incoming request
$this->validate($request, [
'name' => 'required|string',
'email' => 'required|email|unique:users',
'password' => 'required|confirmed',
]);
try {
$user = new User;
$user->name = $request->input('name');
$user->email = $request->input('email');
$plainPassword = $request->input('password');
$user->password = app('hash')->make($plainPassword);
$user->save();
//return successful response
return response()->json(['user' => $user, 'message' => 'CREATED'], 201);
} catch (\Exception $e) {
//return error message
return response()->json(['message' => 'User Registration Failed!'], 409);
}
}
}
Registre um usuário (use POSTMAN) com rota localhost:8000/api/register e você deverá obter uma resposta bem-sucedida como esta
Login do usuário
Puxe o pacote de autenticação JWT.
$ composer require tymon/jwt-auth:dev-develop
Generate your API secret
$ php artisan jwt:secret
create file config/auth.php
with below config
//config.auth.php
<?php
return [
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => \App\User::class
]
]
];
Faça algumas alterações em seu modelo de usuário (app / User.php) para se adequar aos requisitos de tymon / jwt-auth. Fique atento a tudo o que inclui "JWT".
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Laravel\Lumen\Auth\Authorizable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
use Authenticatable, Authorizable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email'
];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'password',
];
/**
* 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 [];
}
}
Make some changes to bootstrap/app.php
//before
// $app->routeMiddleware([
// 'auth' => App\Http\Middleware\Authenticate::class,
// ]);
//After
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]);
//before
// $app->register(App\Providers\AppServiceProvider::class);
// $app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
//After
// $app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
// Add this line
$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);
Add login route in routes/web.php
// API route group
$router->group(['prefix' => 'api'], function () use ($router) {
// Matches "/api/register
$router->post('register', 'AuthController@register');
// Matches "/api/login
$router->post('login', 'AuthController@login');
});
Adicione um método respondWithToken global à classe Controller em app / Http / Controllers / Controller.php. Isso é para que possamos acessá-lo de qualquer outro controlador.
...
//import auth facades
use Illuminate\Support\Facades\Auth;
//Add this method to the Controller class
protected function respondWithToken($token)
{
return response()->json([
'token' => $token,
'token_type' => 'bearer',
'expires_in' => Auth::factory()->getTTL() * 60
], 200);
}
Add a login method to your AuthController class in app/Http/Controllers/AuthController.php
...
//import auth facades
use Illuminate\Support\Facades\Auth;
...
/**
* Get a JWT via given credentials.
*
* @param Request $request
* @return Response
*/
public function login(Request $request)
{
//validate incoming request
$this->validate($request, [
'email' => 'required|string',
'password' => 'required|string',
]);
$credentials = $request->only(['email', 'password']);
if (! $token = Auth::attempt($credentials)) {
return response()->json(['message' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
Faça o login de um usuário usando a rota localhost:8000/api/login e você deverá obter uma resposta bem-sucedida como esta:
.
Rotas autenticadas
Para o nosso grand finale, vamos fazer algumas rotas autenticadas.
Adicione algumas rotas a routes / web.php
...
// API route group
$router->group(['prefix' => 'api'], function () use ($router) {
// Matches "/api/register
$router->post('register', 'AuthController@register');
// Matches "/api/login
$router->post('login', 'AuthController@login');
// Matches "/api/profile
$router->get('profile', 'UserController@profile');
// Matches "/api/users/1
//get one user by id
$router->get('users/{id}', 'UserController@singleUser');
// Matches "/api/users
$router->get('users', 'UserController@allUsers');
});
...
Crie um arquivo app / Http / Controllers / UserController.php e preencha-o com este código de aparência elegante.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\User;
class UserController extends Controller
{
/**
* Instantiate a new UserController instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Get the authenticated User.
*
* @return Response
*/
public function profile()
{
return response()->json(['user' => Auth::user()], 200);
}
/**
* Get all User.
*
* @return Response
*/
public function allUsers()
{
return response()->json(['users' => User::all()], 200);
}
/**
* Get one user.
*
* @return Response
*/
public function singleUser($id)
{
try {
$user = User::findOrFail($id);
return response()->json(['user' => $user], 200);
} catch (\Exception $e) {
return response()->json(['message' => 'user not found!'], 404);
}
}
}
Below is an example call to one of the three newly added endpoints
Espero que este artigo o tenha ajudado de alguma forma e que você aproveite esse conhecimento para implantar APIs incríveis no futuro próximo. Eu gostaria de ver suas contribuições nos comentários também.
Fonte:
- https://github.com/ndiecodes/lumen-auth-example
- https://dev.to/ndiecodes/build-a-jwt-authenticated-api-with-lumen-2afm
Donate to Site
Renato
Developer