Lidar com autenticação em aplicativos de página única (SPA) pode ser complicado. Freqüentemente, os desenvolvedores simplesmente usam o armazenamento local para salvar os tokens dos usuários. No entanto, o armazenamento local não é muito seguro, por isso geralmente é recomendado usar algo que ofereça mais proteção, como cookies.

Neste tutorial, mostraremos como implementar autenticação em um SPA Nuxt.js usando Laravel Sanctum . Para demonstrar como isso funciona, vamos percorrer o processo de construção de um aplicativo Nuxt.js simples com autenticação alimentada por uma API do Laravel.

Cobriremos o seguinte em detalhes e exemplos:

Para acompanhar esta demonstração, você deve ter conhecimento básico de Laravel e Nuxt.js .

O que é Laravel Sanctum?

Laravel Sanctum é um pacote Laravel para autenticação de SPAs, aplicativos móveis e APIs básicas baseadas em tokens. Dependendo do que você está construindo, o Laravel Sanctum pode ser usado para gerar tokens de API para usuários ou autenticar usuários com uma sessão do Laravel.

Criando um aplicativo Laravel

Vamos começar nossa demonstração criando um novo aplicativo Laravel.

Para criar um novo aplicativo Laravel, use o Instalador Laravel :

 laravel new laravel-sanctum-nuxtjs-api

Depois de fazer isso, execute o seguinte comando para iniciar o aplicativo:

 cd laravel-sanctum-nuxtjs-api
php artesão servir

O aplicativo agora deve estar sendo executado em http://127.0.0.1:8000 . Vamos deixá-lo funcionando pelo resto do tutorial.

Configurando o Laravel Sanctum

Para configurar o Sanctum, primeiro instale-o:

 compositor requer laravel/sanctum

Depois de instalado, você pode publicar os arquivos do fornecedor do Sanctum:

 fornecedor de artesão de php: publicar--provider="Laravel \ Sanctum \ SanctumServiceProvider"

Isso cria um arquivo sanctum.php dentro do diretório config , que é usado para configurar o Sanctum. Ele também criará um arquivo de migração para uma tabela personal_access_tokens , que é usada para armazenar tokens de acesso.

Antes de executarmos as migrações, vamos configurar o banco de dados para nosso aplicativo. Para manter as coisas simples, usaremos SQLite .

Crie um arquivo database.sqlite :

 touch database/database.sqlite

Atualize o arquivo .env para refletir isso:

//.env DB_CONNECTION=sqlite
DB_DATABASE=/absoluto/caminho/para/banco de dados.sqlite

Agora, executamos as migrações do banco de dados:

 php artesão migrar

Para que o Sanctum gere tokens de acesso para usuários, o modelo Usuário precisa usar o atributo HasApiTokens :

//app/Models/User.php use Laravel \ Sanctum \ HasApiTokens; classe User extends Authenticatable
{ use HasApiTokens, HasFactory, Notifiable;
}

Um dos benefícios de usar o Sanctum é que ele usa os cookies de sessão normais do Laravel para autenticação em um SPA.

Para configurar os domínios dos quais nosso SPA fará a solicitação, vá para o arquivo sanctum.php e atualize a chave stateful de acordo:

//config/sanctum.php 'com estado'=& gt; explodir (',', env ( 'SANCTUM_STATEFUL_DOMAINS', 'localhost, localhost: 3000,127.0.0.1,127.0.0.1: 8000,:: 1'
)),

Em vez de atualizar o arquivo diretamente, usaremos as variáveis ​​de ambiente:

//.env SESSION_DRIVER=cookie
SANCTUM_STATEFUL_DOMAINS=localhost: 3000
SESSION_DOMAIN=.localhost

Normalmente, os domínios devem incluir seus domínios locais e de produção, que acessam sua API por meio de um SPA. Eu o defini para apenas localhost: 3000 porque é onde o SPA será executado. Além dos domínios com estado, também definimos o driver e o domínio da sessão.

Em seguida, precisamos registrar o middleware do Sanctum no grupo de middleware api dentro do arquivo app/Http/Kernel.php :

//app/Http/Kernel.php use Laravel \ Sanctum \ Http \ Middleware \ EnsureFrontendRequestsAreStateful; 'api'=& gt; [ GarantirFrontendRequestsAreStateful:: class, ...
]

Este middleware irá garantir que as solicitações recebidas de nosso SPA possam ser autenticadas usando os cookies de sessão do Laravel.

Por último, vamos garantir que a configuração CORS de nosso aplicativo esteja retornando o cabeçalho Access-Control-Allow-Credentials com um valor True . Podemos fazer isso atualizando o cors.php da seguinte maneira:

//config/cors.php 'support_credentials'=& gt; verdade

Construindo uma API do Laravel

Com toda a configuração feita, vamos começar a construir nossa API do Laravel. Para manter as coisas simples, a API conterá apenas endpoints para autenticar usuários, buscar usuários autenticados e desconectar usuários.

Obviamente, os usuários precisam ser registrados antes de realizar a autenticação. Então, vamos espalhar o banco de dados com um usuário fictício que podemos usar para testar o sistema de autenticação. Faça isso diretamente em DatabaseSeeder.php :

//database/seeders/DatabaseSeeder.php use App \ Models \ User; Usuário:: criar ([ 'nome'=& gt;'John Doe', 'email'=& gt;'[email protected]', 'senha'=& gt; bcrypt ('senha'),
]);

Em seguida, execute o semeador:

 php artisan db: seed

Crie o endpoint /login dentro de routes/web.php :

//routes/web.php Route:: post ('login','AuthController @ login');

Em seguida, crie o AuthController :

 php artisan make: controlador AuthController

Vamos adicionar o método login :

//app/Http/Controllers/AuthController.php use Illuminate \ Support \ Facades \ Auth; login de função pública (solicitação $ solicitação)
{ if (Auth:: try ($ request-& gt; only ('email','password'))) { $ request-& gt; session ()-& gt; regenerate (); } resposta de retorno ()-& gt; json ([ 'mensagem'=& gt;'Detalhes de login inválidos' ], 401);
}

Aqui, tentamos autenticar o usuário com os detalhes fornecidos. Se nenhuma correspondência for encontrada, simplesmente retornamos uma resposta JSON apropriada. Caso contrário, uma sessão é iniciada para o usuário.

Dentro de routes/web.php , crie o endpoint /logout :

//routes/web.php Route:: post ('logout','AuthController @ logout');

Para adicionar a funcionalidade de logout:

//app/Http/Controllers/AuthController.php logout de função pública (solicitação $ solicitação)
{ Auth:: logout (); $ request-& gt; session ()-& gt; invalidate (); $ request-& gt; session ()-& gt; regenerateToken ();
}

logout () remove os detalhes do usuário da sessão. Em seguida, invalidamos a sessão do usuário e, por último, regeneramos o token CSRF.

Como faremos solicitações para essas rotas de um domínio diferente-isto é, do SPA-vamos garantir que as solicitações de origem cruzada sejam permitidas para /login e /logout adicionando-os ao array path dentro de config/cors.php :

//config/cors.php 'caminhos'=& gt; [ ..., 'Conecte-se', 'sair',
],

Para adicionar a implementação para buscar um usuário autenticado, crie o endpoint /api/user dentro de routes/api.php :

//routes/api.php Route:: get ('user','AuthController @ me');

Em seguida, adicione o método me :

//app/Http/Controllers/AuthController.php public function me (Request $ request)
{ resposta de retorno ()-& gt; json ([ 'dados'=& gt; $ request-& gt; user (), ]);
}

Aqui, simplesmente retornamos uma resposta JSON contendo o usuário autenticado no momento.

Como você deve ter adivinhado, o endpoint /auth/user estará acessível apenas para usuários autenticados. Então, vamos ter certeza disso usando a proteção autenticada sanctum .

Atualize a rota da seguinte maneira:

//routes/api.php Route:: get ('/auth/user','AuthController @ me')-& gt; middleware ('auth: sanctum');

Isso garantirá que as solicitações ao endpoint contenham um cabeçalho de autorização com um token válido.

Por último, vamos descomentar a linha abaixo dentro de RouteServiceProvider.php :

//app/Providers/RouteServiceProvider.php protegido $ namespace='App \\ Http \\ Controllers';

Criação de um aplicativo Nuxt.js

Agora, vamos passar para o próprio SPA. Começaremos criando um novo aplicativo Nuxt.js.

Para criar a aplicativo Nuxt.js , basta usar o comando abaixo:

 npx create-nuxt-app laravel-sanctum-nuxtjs-app

Quando solicitado, selecione as opções que fazem sentido para você. Aqui está o que selecionei:

Nuxt prompt select

Assim que a instalação for concluída, inicie o aplicativo:

 cd laravel-sanctum-nuxtjs-app
npm run dev

Para autenticação, usaremos o módulo nuxt/auth .

Para instalar o módulo nuxt/auth:

 npm install--save-exact @ nuxtjs/auth-next

Em seguida, adicione @ nuxtjs/auth-next ao array modules de nuxt.config.js :

//nuxt.config.js { módulos: [ ..., '@ nuxtjs/auth-next', ]
}

Finalmente, atualize o objeto axios como mostrado abaixo:

//nuxt.config.js axios: { credenciais: verdadeiras,
},

Criação de uma página de login

Para estilizar nossa página de login, usaremos Bulma CSS , que instalamos ao criar o aplicativo Nuxt.js.

Vamos criar a página de login. Dentro do diretório pages , crie um arquivo login.vue e adicione o seguinte código:

//páginas/login.vue & lt; template & gt; & lt; classe de seção="seção"& gt; & lt; div class="contêiner"& gt; & lt; div class="as colunas estão centradas"& gt; & lt; div class="coluna é um terço"& gt; & lt; h2 class="título centrado no texto"& gt; Login & lt;/h2 & gt; & lt; form method="post"@ submit.prevent="login"& gt; & lt; div class="campo"& gt; & lt; label class="label"& gt; Email & lt;/label & gt; & lt; div class="controle"& gt; & lt; input type="email"class="input"v-model="email"obrigatório/& gt; & lt;/div & gt; & lt;/div & gt; & lt; div class="campo"& gt; & lt; label class="label"& gt; Senha & lt;/label & gt; & lt; div class="controle"& gt; & lt; entrada type="senha" classe="entrada" v-model="senha" requerido /& gt; & lt;/div & gt; & lt;/div & gt; & lt; div class="controle"& gt; & lt; button type="submit"class="button is-dark is-fullwidth"& gt; Conecte-se & lt;/botão & gt; & lt;/div & gt; & lt;/form & gt; & lt;/div & gt; & lt;/div & gt; & lt;/div & gt; & lt;/seção & gt;
& lt;/template & gt;

Aqui, temos um formulário de login básico, que, quando submetido, chama um método login :

Visual do formulário de login básico

Antes de criarmos o método login , vamos configurar o nuxt-auth para fazer uso do Laravel Sanctum. Podemos fazer isso adicionando o snippet abaixo dentro de nuxt.config.js :

//nuxt.config.js auth: { estratégias: { laravelSanctum: { provedor:'laravel/sanctum', url:'http://localhost: 8000', }, },
},

Observação: O domínio definido como url deve ser igual ao SPA. Como o SPA está sendo executado em http://localhost: 3000 , o url está definido como http://localhost: 8000 .

Definimos o Laravel Sanctum provider como a estratégia que o módulo nuxt-auth usará para autenticação. Sob o capô, o provedor Laravel Sanctum faz solicitações para:

  • /sanctum/csrf-cookie , que emite um cookie XSRF-TOKEN como cabeçalho
  • /login , o endpoint que criamos dentro de routes/web.php , ao fazer login
  • A rota /api/user em nosso aplicativo Laravel ao buscar o usuário autenticado.

Agora, podemos adicionar a funcionalidade para o método login dentro de login.vue :

//páginas/login.vue & lt; script & gt;
export default { dados() { Retorna { o email:'', senha:'', } }, métodos: { login assíncrono () { aguarde isso. $ auth.loginWith ('laravelSanctum', { dados: { email: this.email, senha: this.password, }, }) este. $ router.push ('/') }, },
}
& lt;/script & gt;

Primeiro, definimos algumas propriedades de dados. Então temos o método login , onde estamos logando usando o provedor Laravel Sanctum.

Nos bastidores, o provedor primeiro faz uma solicitação a /sanctum/csrf-cookie para obter um token CSRF e defini-lo como um cookie XSRF-TOKEN , que é usado em solicitações subsequentes. Em seguida, ele faz uma solicitação POST para o endpoint /l``ogin . Após o login bem-sucedido, o usuário é redirecionado para a página inicial.

Atualização da página inicial

Por enquanto, a página inicial contém o conteúdo padrão de quando criamos o aplicativo Nuxt.js. Vamos atualizá-lo para exibir o nome do usuário autenticado e uma maneira de fazer logout.

Substitua o conteúdo de pages/index.vue pelo seguinte:

//páginas/index.vue & lt; template & gt; & lt; classe de seção="seção"& gt; & lt; div class="contêiner"& gt; & lt; h1 class="title"& gt; Painel de controle & lt;/h1 & gt; & lt; p & gt; Olá, {{user.name}} & lt;/p & gt; & lt; a href="#"@ click.prevent="logout"& gt; Logout & lt;/a & gt; & lt;/div & gt; & lt;/seção & gt;
& lt;/template & gt; & lt; script & gt;
export default { dados() { Retorna { usuário: este. $ auth.user.data, } }, métodos: { logout assíncrono () { aguarde isso. $ auth.logout () este. $ router.push ('/login') }, },
}
& lt;/script & gt;

Por dentro, o provedor Laravel Sanctum faz uma solicitação ao endpoint /api/user para buscar o usuário autenticado. Podemos obter os detalhes do usuário por meio de this. $ Auth.user , que simplesmente atribuímos a uma propriedade de dados user .

Para fazer logout, simplesmente chamamos o método logout e redirecionamos para a página de login.

Após um login bem-sucedido, devemos obter algo assim:

Retorno do login bem-sucedido

Restringindo o acesso

A página inicial está servindo como a página de perfil, então vamos garantir que apenas usuários autenticados possam acessá-la. Podemos fazer isso usando o middleware auth fornecido pelo nuxt-auth .

Adicione o seguinte código dentro de nuxt.config.js :

//nuxt.config.js roteador: { middleware: ['auth']
},
> 

Agora, quando usuários autenticados tentarem acessar a página inicial, eles serão redirecionados para a página de login.

Conclusão

Neste tutorial, mostramos como usar o Laravel Sanctum para implementar a autenticação em um SPA Nuxt.js.

Para saber mais sobre o Laravel Sanctum, verifique os documentos do Laravel Sanctum .

Você pode obter o código-fonte completo para nossa demonstração API e SPA no GitHub.

A postagem Tutorial do Laravel Sanctum: Autenticação de SPAs Nuxt.js apareceu primeiro no LogRocket Blog .

Source link