{"id":71,"date":"2024-09-17T19:38:00","date_gmt":"2024-09-17T22:38:00","guid":{"rendered":"https:\/\/tromineo.com.br\/blog\/?p=71"},"modified":"2025-11-02T15:05:01","modified_gmt":"2025-11-02T18:05:01","slug":"configurando-autenticacao-no-laravel-11x-com-sanctum","status":"publish","type":"post","link":"https:\/\/tromineo.com.br\/blog\/index.php\/2024\/09\/17\/configurando-autenticacao-no-laravel-11x-com-sanctum\/","title":{"rendered":"Configurando autentica\u00e7\u00e3o no Laravel 11x com Sanctum"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A autentica\u00e7\u00e3o no Laravel pode ser feita com o aux\u00edlio dos pacotes <strong>Sanctum<\/strong> ou <strong>Passport<\/strong>. O <strong>Passport<\/strong> \u00e9 utilizado para autentica\u00e7\u00f5es mais complexas e espec\u00edficas enquanto o Sanctum \u00e9 uma solu\u00e7\u00e3o mais simples e r\u00e1pida, fornecendo um mecanismo de autentica\u00e7\u00e3o via token.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por padr\u00e3o, esses pacotes n\u00e3o vem configurados na instala\u00e7\u00e3o do laravel ent\u00e3o nesse post vou mostrar como fazer isso, partindo do zero.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para criar um novo projeto usando o framework Laravel precisamos primeiro instalar o gerenciador de depend\u00eancias do php Composer com o seguinte comando:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -sS https:\/\/getcomposer.org\/installer | php<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Criar um novo projeto no Laravel.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> composer create-project --prefer-dist laravel\/laravel nomeDoProjeto <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Como estamos falando de autentica\u00e7\u00e3o, vamos precisar ter uma conex\u00e3o ativa com o nosso banco de dados configurada no arquivo .env do projeto . <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As configura\u00e7\u00f5es podem ser feitas na se\u00e7\u00e3o com as informa\u00e7\u00f5es <strong>DB_*<\/strong> (&#8216;DB_CONNECTION&#8217;, &#8216;DB_GOST&#8217;, &#8216;DB_PORT&#8217;, etc) do arquivo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por padr\u00e3o, o Laravel n\u00e3o vai vir com o arquivo api.php configurado ent\u00e3o precisamos do aux\u00edlio do artisan para cria\u00e7\u00e3o do api.php assim como a instala\u00e7\u00e3o do pacote Sanctum.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vamos rodar o seguinte comando para isso:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php artisan install:api<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Seguindo esses passos voc\u00ea deve ter uma classe model de Usu\u00e1rio no namespace <strong>App\\Models\\User.php<\/strong>. Nela, vamos precisar realizar a inclus\u00e3o da trait &#8216;<strong>HasApiTokens<\/strong>&#8216;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>use Laravel\\Sanctum\\HasApiTokens;<\/code> -&gt; Import da trait na classe <strong>User.php<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>use HasApiTokens<\/code> -&gt; declara\u00e7\u00e3o do uso da trait no escopo da classe.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ela deve ficar assim:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\nnamespace App\\Models;\n\n\/\/ use Illuminate\\Contracts\\Auth\\MustVerifyEmail;\nuse Illuminate\\Database\\Eloquent\\Factories\\HasFactory;\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Illuminate\\Notifications\\Notifiable;\nuse Laravel\\Sanctum\\HasApiTokens;\n\nclass User extends Authenticatable\n{\n    use HasFactory, Notifiable, HasApiTokens;\n\n    \/**\n     * The attributes that are mass assignable.\n     *\n     * @var array&lt;int, string&gt;\n     *\/\n    protected $fillable = &#91;\n        'name',\n        'email',\n        'password',\n    ];\n\n    \/**\n     * The attributes that should be hidden for serialization.\n     *\n     * @var array&lt;int, string&gt;\n     *\/\n    protected $hidden = &#91;\n        'password',\n        'remember_token',\n    ];\n\n    \/**\n     * Get the attributes that should be cast.\n     *\n     * @return array&lt;string, string&gt;\n     *\/\n    protected function casts(): array\n    {\n        return &#91;\n            'email_verified_at' =&gt; 'datetime',\n            'password' =&gt; 'hashed',\n        ];\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Depois disso, vamos criar uma classe no n\u00edvel dos controllers que vai registrar um novo usu\u00e1rio e realizar o login dele tamb\u00e9m, usando o artisan para nos ajudar.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>php artisan make:controller AuthController<\/code><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Depois vamos configurar rotas de autenticar e login no arquivo <strong>api.php<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Route::post('\/register', &#91;AuthController::class, 'register']);\nRoute::post('\/login', &#91;AuthController::class, 'login']);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">O m\u00e9todo <strong>register<\/strong> vai ser respons\u00e1vel por criar um novo usu\u00e1rio enquanto o <strong>login<\/strong> vai autenticar um usu\u00e1rio registrado e retornar um token de acesso.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O m\u00e9todo <strong>register<\/strong> fica assim:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    public function register(Request $request)\n    {\n        $request-&gt;validate(&#91;\n            'name' =&gt; &#91;'required', 'string', 'max:255'],\n            'email' =&gt; &#91;'required', 'string', 'email', 'max:255', 'unique:users'],\n            'password' =&gt; &#91;'required', 'string', 'min:8', 'confirmed'],\n        ]);\n\n        $user = User::create(&#91;\n            'name' =&gt; $request-&gt;name,\n            'email' =&gt; $request-&gt;email,\n            'password' =&gt; Hash::make($request-&gt;password),\n        ]);\n\n        $token = $user-&gt;createToken('auth_token')-&gt;plainTextToken;\n\n        return response()-&gt;json(&#91;\n            'message' =&gt; 'Successfully registered',\n            'user' =&gt; $user,\n            'token' =&gt; $token\n        ]);\n\n    }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">E o m\u00e9todo <strong>login<\/strong> deve ficar da seguinte forma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    public function login(Request $request){\n\n        $request-&gt;validate(&#91;\n            'email' =&gt; &#91;'required', 'string', 'email', 'max:255'],\n            'password' =&gt; &#91;'required', 'string', 'min:8'],\n        ]);\n\n        $user = User::where('email', $request-&gt;email)-&gt;first();\n        \n        if(!$user || !Hash::check($request-&gt;password, $user-&gt;password)){\n            return response(&#91;'message'=&gt; 'Dados inv\u00e1lidos'], 401);\n        }\n\n        $token = $user-&gt;createToken('auth_token')-&gt;plainTextToken;\n\n        return response()-&gt;json(&#91;\n            'user'=&gt;$user,\n            'token'=&gt;$token\n        ]);\n\n    }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A partir da\u00ed, j\u00e1 conseguimos criar novo usu\u00e1rio na rota &#8216;\/<strong>register<\/strong>&#8216; e efetuar login com esse usu\u00e1rio na rota &#8216;<strong>\/login<\/strong>&#8216;. Ao efetuar o login recebemos o nosso token de autentica\u00e7\u00e3o que pode ser usado para acessar as rotas que est\u00e3o protegidas pelo middleware Sanctum.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"765\" height=\"313\" src=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image.png\" alt=\"\" class=\"wp-image-94\" srcset=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image.png 765w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-300x123.png 300w\" sizes=\"auto, (max-width: 765px) 100vw, 765px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">No arquivo <strong>api.php<\/strong> declaramos as rotas que v\u00e3o pedir a autentica\u00e7\u00e3o:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"865\" height=\"135\" src=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-1.png\" alt=\"\" class=\"wp-image-95\" srcset=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-1.png 865w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-1-300x47.png 300w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-1-768x120.png 768w\" sizes=\"auto, (max-width: 865px) 100vw, 865px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><br>Para testar o acesso com o token ent\u00e3o criamos o <strong>controller<\/strong> e <strong>model<\/strong> &#8220;Post&#8221; (uma postagem).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php artisan make:controller PostController<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>php artisan make:model Post -m<\/code><\/pre>\n\n\n\n<p class=\"has-small-font-size wp-block-paragraph\">*Quando criamos uma nova model podemos passar o par\u00e2metro &#8220;<strong>-m<\/strong>&#8221; para fazer a cria\u00e7\u00e3o autom\u00e1tica de uma migration que vai fazer a cria\u00e7\u00e3o de uma tabela relacional para esse modelo que estamos criando.  No meu caso, a migration ficou assim:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    \/**\n     * Run the migrations.\n     *\/\n    public function up(): void\n    {\n        Schema::create('posts', function (Blueprint $table) {\n            $table-&gt;id();\n            $table-&gt;string('title');\n            $table-&gt;text('content');\n            $table-&gt;foreignId('user_id')-&gt;constrained()-&gt;onDelete('cascade');\n            $table-&gt;timestamps();\n        });\n    }\n\n    \/**\n     * Reverse the migrations.\n     *\/\n    public function down(): void\n    {\n        Schema::dropIfExists('posts');\n    }\n};\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Rodamos essa nova migra\u00e7\u00e3o com o artisan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php artisan migrate<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">E iniciamos o ambiente local de desenvolvimento com o comando:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php artisan serve<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Agora, se tentarmos acessar as novas rotas que criamos sem passar qualquer autentica\u00e7\u00e3o, devemos receber o erro:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"978\" height=\"604\" src=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-2.png\" alt=\"\" class=\"wp-image-96\" srcset=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-2.png 978w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-2-300x185.png 300w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-2-768x474.png 768w\" sizes=\"auto, (max-width: 978px) 100vw, 978px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Mas usando o token que geramos h\u00e1 pouco, temos o seguinte resultado:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"637\" src=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-3-1024x637.png\" alt=\"\" class=\"wp-image-97\" srcset=\"https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-3-1024x637.png 1024w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-3-300x187.png 300w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-3-768x478.png 768w, https:\/\/tromineo.com.br\/blog\/wp-content\/uploads\/2024\/09\/image-3.png 1227w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Com apenas esses passos conseguimos configurar o pacote Sanctum para controlar o acesso \u00e0 nossa aplica\u00e7\u00e3o. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A autentica\u00e7\u00e3o no Laravel pode ser feita com o aux\u00edlio dos pacotes Sanctum ou Passport. O Passport \u00e9 utilizado para autentica\u00e7\u00f5es mais complexas e espec\u00edficas enquanto o Sanctum \u00e9 uma solu\u00e7\u00e3o mais simples e r\u00e1pida, fornecendo um mecanismo de autentica\u00e7\u00e3o via token. Por padr\u00e3o, esses pacotes n\u00e3o vem configurados na instala\u00e7\u00e3o do laravel ent\u00e3o nesse [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":101,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25,28],"tags":[3,9,5,10,4],"class_list":["post-71","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","category-php","tag-development","tag-laravel","tag-programacao","tag-sanctum","tag-software"],"_links":{"self":[{"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/posts\/71","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=71"}],"version-history":[{"count":19,"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/posts\/71\/revisions"}],"predecessor-version":[{"id":162,"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/posts\/71\/revisions\/162"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/media\/101"}],"wp:attachment":[{"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=71"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=71"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tromineo.com.br\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=71"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}