DEV Community

Cover image for Laravel API Authentication Using LARAVEL SANCTUM With Angular (front-end)
Chabba Saad
Chabba Saad

Posted on

Laravel API Authentication Using LARAVEL SANCTUM With Angular (front-end)

Make REST API AUTHENTICATION in LARAVEL 10 USING LARAVEL SANCTUM

Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs.

first let create a new folder for your Laravel Project

Installation Steps
Step 1

composer create-project --prefer-dist laravel/laravel my-laravel-api
Enter fullscreen mode Exit fullscreen mode

Step 2

composer require laravel/sanctum
Enter fullscreen mode Exit fullscreen mode

After successfully install package, we need to publish configuration file with following command:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Enter fullscreen mode Exit fullscreen mode

we require to get default migration for create new sanctum tables in our database. so let's run bellow command.

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Next, we need to add middleware for sanctum api, so let's add as like bellow:

Open you kernel page : app/Http/Kernel.php

   'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
Enter fullscreen mode Exit fullscreen mode

**
API Authentication Routes**

Create AuthController to handle all authentication realted to API

php artisan make:controller Api\\AuthController
Enter fullscreen mode Exit fullscreen mode

In routes\api.php file update the API

Route::post('/auth/register', [AuthController::class, 'createUser']);
Route::post('/auth/login', [AuthController::class, 'loginUser']);
Enter fullscreen mode Exit fullscreen mode

Now update AuthContoller with

<?php

namespace App\Http\Controllers\Api;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class AuthController extends Controller
{
    /**
     * Create User
     * @param Request $request
     * @return User 
     */
    public function createUser(Request $request)
    {
        try {
            //Validated
            $validateUser = Validator::make($request->all(), 
            [
                'name' => 'required',
                'email' => 'required|email|unique:users,email',
                'password' => 'required'
            ]);

            if($validateUser->fails()){
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateUser->errors()
                ], 401);
            }

            $user = User::create([
                'name' => $request->name,
                'email' => $request->email,
                'password' => Hash::make($request->password)
            ]);

            return response()->json([
                'status' => true,
                'message' => 'User Created Successfully',
                'token' => $user->createToken("API TOKEN")->plainTextToken
            ], 200);

        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }

    /**
     * Login The User
     * @param Request $request
     * @return User
     */
    public function loginUser(Request $request)
    {
        try {
            $validateUser = Validator::make($request->all(), 
            [
                'email' => 'required|email',
                'password' => 'required'
            ]);

            if($validateUser->fails()){
                return response()->json([
                    'status' => false,
                    'message' => 'validation error',
                    'errors' => $validateUser->errors()
                ], 401);
            }

            if(!Auth::attempt($request->only(['email', 'password']))){
                return response()->json([
                    'status' => false,
                    'message' => 'Email & Password does not match with our record.',
                ], 401);
            }

            $user = User::where('email', $request->email)->first();

            return response()->json([
                'status' => true,
                'message' => 'User Logged In Successfully',
                'token' => $user->createToken("API TOKEN")->plainTextToken
            ], 200);

        } catch (\Throwable $th) {
            return response()->json([
                'status' => false,
                'message' => $th->getMessage()
            ], 500);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Here are the results.

Register Api in insomnia

login Api in insomnia

now let create a login and register pages in Angular

ng new Authentification-App
Enter fullscreen mode Exit fullscreen mode

Change into the project directory by running cd my-app.

Next, we need to install some dependencies. Run the following command to install axios and rxjs:

npm install axios rxjs
Enter fullscreen mode Exit fullscreen mode

then let create a new folder call it Components manually

ng generate component components/login
ng generate component components/register
Enter fullscreen mode Exit fullscreen mode

*in the recent version of angular we need to create a folder of environments in src folder *

 export const environment = {
    production: false,
    api_url: 'http://localhost:8000/api'
};
Enter fullscreen mode Exit fullscreen mode

and let add httpclient and formsmodule to our app.modules.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './components/login/login.component';
import { RegisterComponent } from './components/register/register.component';
import { FormsModule } from '@angular/forms';
import { DashboardComponent } from './components/dashboard/dashboard.component';
@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    RegisterComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Enter fullscreen mode Exit fullscreen mode

then let create our routing pages in the app-routing.module.ts :

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'register', component: RegisterComponent },
  { path: 'dashboard', component: DashboardComponent }
];
Enter fullscreen mode Exit fullscreen mode

login.component.ts

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { Router } from '@angular/router';
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})





export class LoginComponent {
  email: string = "";
  password: string = "";
  constructor(private http: HttpClient, private router: Router) { }

  onSubmit() {
    const formData = new FormData();
    formData.append('email', this.email);
    formData.append('password', this.password);

    this.http.post(`${environment.api_url}/auth/login`, formData)
      .subscribe(
        response => console.log(response),

        error => console.log(error)
      );
    // If login successful, navigate to dashboard page
    this.router.navigate(['/dashboard']);

  }
}

Enter fullscreen mode Exit fullscreen mode

login.component.html

<div class="container mt-5">
    <div class="row justify-content-center">
      <div class="col-md-6">
        <div class="card">
          <div class="card-header">
            <h4>Login</h4>
          </div>
          <div class="card-body">
            <form>
              <div class="form-group">
                <label for="email">Email</label>
                <input type="email" class="form-control" id="email" [(ngModel)]="email" name="email">
              </div>
              <div class="form-group">
                <label for="password">Password</label>
                <input type="password" class="form-control" id="password" [(ngModel)]="password" name="password">
              </div>
              <button type="submit" class="btn btn-primary" (click)="onSubmit()">Login</button>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
Enter fullscreen mode Exit fullscreen mode

register.component.ts

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { Router } from '@angular/router';
@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.css']
})

export class RegisterComponent {
  email: string = "";
  password: string = "";
  name: string = "";
  passwordConfirmation: string = "";
  constructor(private http: HttpClient, private router: Router) { }

  onSubmit() {
    const formData = new FormData();
    formData.append('name', this.name);
    formData.append('email', this.email);
    formData.append('password', this.password);
    //formData.append('password_confirmation', this.passwordConfirmation);

    this.http.post(`${environment.api_url}/auth/register`, formData)
      .subscribe(
        response => console.log(response),
        error => console.log(error)
      );
  }
}
Enter fullscreen mode Exit fullscreen mode

register.component.html

<div class="container mt-5">
    <div class="row justify-content-center">
      <div class="col-md-6">
        <div class="card">
          <div class="card-header">
            <h4>Register</h4>
          </div>
          <div class="card-body">
            <form>
              <div class="form-group">
                <label for="name">Name</label>
                <input type="text" class="form-control" id="name" [(ngModel)]="name" name="name">
              </div>
              <div class="form-group">
                <label for="email">Email</label>
                <input type="email" class="form-control" id="email" [(ngModel)]="email" name="email">
              </div>
              <div class="form-group">
                <label for="password">Password</label>
                <input type="password" class="form-control" id="password" [(ngModel)]="password" name="password">
              </div>
              <div class="form-group">
                <label for="passwordConfirmation">Confirm Password</label>
                <input type="password" class="form-control" id="passwordConfirmation" [(ngModel)]="passwordConfirmation" name="passwordConfirmation">
              </div>
              <button type="submit" class="btn btn-primary" (click)="onSubmit()">Register</button>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
Enter fullscreen mode Exit fullscreen mode

here is the final result :

after login you will find a 200 status response in the console enjoy !!

dont forget to add cdn of bootstrap to your index html in angular porject :

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
Enter fullscreen mode Exit fullscreen mode

Top comments (0)