Ionic/Laravel 01 - Login com Passport


Esse tutorial é voltado para pessoas que já tenha pelo menos um conhecimento básico de Ionic Framework e Laravel. Decidi fazer essa sequência de tutoriais para dar um norte para a galera que deseja desenvolver um app usando esses dois frameworks, mas não tem ideia por onde começar. Ao final da sequência de tutoriais Ionic/Laravel você terá um app de Lista de Compras, que consumirá dados da API que será desenvolvida usando o Laravel. Será utilizado a biblioteca Passport do Laravel para fazer a autenticação dos usuários. Cada usuário poderá visualizar e alterar somente as suas próprias listas.

Primeiramente vou começar montando o back-end do login no Laravel.

Etapa 1: Instalar o Laravel

composer create-project laravel/laravel lista-de-compras

Etapa 2: Instalar o Passport

composer require laravel/passport
Depois de instalar o Passport, abra o arquivo config/app.php e adicione o provedor de serviços.
'provider=>[
     Laravel\Passport\PassportServiceProvider::class,
],

Etapa 3: Adicionar o BD

Agora crie um banco de dados com o nome de lista no seu servidor e adicione as informações de acesso dele no arquivo .env.
APP_NAME=ListaDeCompras
APP_ENV=local
APP_KEY=base64:eyNuCHxY5PgicLV2fl0Z7zD7gqegDye8Klll9CVf3Fo=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=lista
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

Etapa 4: Executar o migrate e o install

O comando abaixo vai gerar as tabelas no seu banco de dados que são necessárias para armazenar clientes e acessar tokens.
php artisan migrate
Em seguida, você deve executar o comando abaixo. Esse comando criará as chaves de criptografia necessárias para gerar tokens de acesso seguro. Além disso, o comando criará clientes de "acesso pessoal" e "concessão de senha", que serão usados ​​para gerar tokens de acesso.
php artisan passport:install

Etapa 5: Configuração do Passport

Agora você terá que fazer alterações em três arquivos diferentes. Deixei em negrito as alterações que precisam ser adicionadas.

app/User.php
<?php

namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
    /**
    * 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',
    ];
}
app/Providers/AuthServiceProvider.php
<?php

namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate; 
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

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(); 
        Passport::routes(); 
    } 
}
config/auth.php
<?php

return [
'guards' => [ 
        'web' => [ 
            'driver' => 'session', 
            'provider' => 'users', 
        ], 
        'api' => [ 
            'driver' => 'passport', 
            'provider' => 'users', 
            'hash' => false,
        ], 
    ],

Etapa 6: Criar as rotas

Todas as rotas do Laravel são definidas em seus arquivos de rota, que estão localizados no diretório routes. Esses arquivos são automaticamente carregados pela estrutura. Essas rotas são atribuídas ao grupo de middleware, que fornece recursos como estado de sessão e proteção CSRF. Como estaremos usando o Laravel para montar a API, vamos adicionar nossas rotas ao arquivo routes/api.php.
use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::post('login', 'Api\UserController@login');
Route::post('register', 'Api\UserController@register');
Route::group(['middleware' => 'auth:api'], function(){
    Route::post('details', 'Api\UserController@details');
});

Etapa 7: Criar o controlador

Para finalizar vamos criar o controller aonde será inserido os métodos de autenticação. Execute o comando abaixo:
php artisan make:controller Api/UserController
Agora cole o seguinte código no arquivo App/Http/Controllers/Api/UserController.php:
<?php

namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;
class UserController extends Controller
{
    public $successStatus = 200;
    /**
     * login api
     *
     * @return \Illuminate\Http\Response
     */
    public function login() {
        if (Auth::attempt(['email' => request('email'), 'password' => request('password')])){
            $user = Auth::user();
            $success['token'] =  $user->createToken('MyApp')-> accessToken;
            return response()->json(['success' => $success], $this-> successStatus);
        }
        else {
            return response()->json(['error'=>'Não autorizado'], 401);
        }
    }
    /**
     * Register api
     *
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);
        if ($validator->fails()) {
            return response()->json(['error'=>$validator->errors()], 401);
        }
        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] =  $user->createToken('MyApp')-> accessToken;
        $success['name'] =  $user->name;
        return response()->json(['success'=>$success], $this-> successStatus);
    }
     /**
     * details api
     *
     * @return \Illuminate\Http\Response
     */
    public function details()
    {
        $user = Auth::user();
        return response()->json(['success' => $user], $this-> successStatus);
    }
}
Agora execute o seguinte comando para rodar nossa API:
php artisan serve

Testando a API

Para testar a API utilizei o Postman para simular as requisições.

Registrar usuário:

Login:

Detalhes:

Para obter os detalhes do usuário é necessário enviar o token capturado durante o login. O token precisa ser adicionado na header da requisição com os seguintes cabeçalhos:
'headers' => [ 
     'Accept' => 'application/json',
     'Authorization' => 'Bearer '.$accessToken,
]
Em nossa aplicação estaremos usando esse token para validar o login dos usuários, pois como dito antes cada usuário só terá acesso aos seus dados particulares.

Caso queira reaproveitar o esqueleto gerado nesse tutorial, para usar em outros projetos e não ter que repetir todos os passos novamente, copie ele em outra pasta. Assim vc precisará apenas alterar as info do arquivo .env e executar os comandos da Etapa 4.

Qualquer dúvida que tiverem, deixem nos comentários!!! 🙂