Laravel Auth API Standard: Secure and Scalable Authentication Solution by Faizan Ali
Discover the Laravel Auth API Standard, a secure and scalable authentication solution developed by Faizan Ali. This API standard simplifies…
Laravel Auth API Standard: Secure and Scalable Authentication Solution by Faizan Ali

Discover the Laravel Auth API Standard, a secure and scalable authentication solution developed by Faizan Ali. This API standard simplifies the integration of strong authentication features into your Laravel projects, ensuring better security and a seamless user experience. Perfect for developers looking for an efficient and reliable way to manage user authentication.
- Set Up the Laravel Project
Use the following command to start a new Laravel project if you haven’t already:
composer create-project --prefer-dist laravel/laravel your-project-name
- Open the directory for your project:
cd your-project-name
3. Configuring the Database
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=api_db
DB_USERNAME=root
DB_PASSWORD=
4. Open your file directory routes/api.php and paste these route in your file
This code snippet defines routes for a Laravel application that handles user authentication and profile management using API endpoints. Here’s a brief explanation:
- Register and Login:
Route::post('register', [UserController::class, 'Register']);: This route allows users to register by sending a POST request to the/registerendpoint.Route::post('login', [UserController::class, 'Login']);: This route allows users to log in by sending a POST request to the/loginendpoint.
- Authenticated Routes (Protected by Sanctum Middleware):
- The routes inside the
Route::groupare protected by theauth:sanctummiddleware, meaning they can only be accessed by authenticated users. Route::get('profile', [UserController::class, 'GetProfile']);: Fetches the authenticated user's profile data.Route::post('update_profile', [UserController::class, 'UpdateProfile']);: Allows the authenticated user to update their profile information.Route::post('update_password', [UserController::class, 'UpdatePassword']);: Enables the authenticated user to change their password.Route::post('logout', [UserController::class, 'Logout']);: Logs out the authenticated user, ending their session.
<?php
use App\Http\Controllers\Api\UserController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/
//Register Api
Route::post('register', [UserController::class, 'Register']);
Route::post('login', [UserController::class, 'Login']);
//get profile
Route::group(['middleware' => ['auth:sanctum']], function(){
Route::get('profile', [UserController::class, 'GetProfile']);
Route::post('update_profile', [UserController::class, 'UpdateProfile']);
Route::post('update_password', [UserController::class, 'UpdatePassword']);
Route::post('logout', [UserController::class, 'Logout']);
});
5. Make a UserController
The UserController in Laravel is responsible for managing user authentication and profile-related operations. It handles user registration, login, profile retrieval, profile updates, password changes, and logout functionality, ensuring a smooth and secure user experience within your Laravel application.
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\LoginUser;
use App\Http\Requests\Api\UpdatePassword;
use App\Http\Requests\Api\UserRegister;
use App\Http\Resources\Api\ProfileResource;
use App\Http\Resources\Api\UpdateProfile;
use App\Models\ActivityLog;
use App\Models\User;
use App\Services\ImageService;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
//Register a user then return a token
public function Register(UserRegister $request)
{
$user = new User();
$user->name = $request->name;
$user->email = $request->email;
$user->password = bcrypt($request->password);
$user->fcm_token = $request->fcm_token;
if($request->hasFile('image')){
$user->image = ImageService::addImage('images/user_profile', $request->image, 'ProfileImage_');
}
$user->save();
$token = $user->createToken('API Token')->plainTextToken;
return $this->success(data: [
'token' => $token
], message: 'Successfully Registered');
}
//Login a user then return a token
public function Login(LoginUser $request)
{
$user = User::where(function ($query) use ($request) {
$query->where('email', $request->email)->first();
})->first();
if (!$user)
return $this->error(message: 'Incorrect Email',code: 403);
if (!auth()->loginUsingId((password_verify($request->password, $user->password)) ? $user->id : 0))
return $this->error(message: 'Incorrect Password',code: 403);
$user = auth()->user();
$token = $user->createToken('API TOKEN')->plainTextToken;
return $this->success(data: [
'token' => $token,
], message: 'Logged in successfully');
}
//Get Profile
public function GetProfile(Request $request)
{
$user = auth()->user();
$result = ProfileResource::make($user);
return $this->success(data: $result, message: 'Success');
}
//update profile
public function UpdateProfile(Request $request){
$auth_user = Auth::user();
$auth_user->name = $request->input('name') ? $request->input('name') : Auth::user()['name'];
if($request->image == null){
if(basename(Auth::user()['image']) == 'avatar.png'){
$auth_user->image = null;
}
else{
$auth_user->image = basename(Auth::user()['image']);
}
}
else{
$auth_user->image = ImageService::updateImage('images/user_profile',$request->image, Auth::user()['image'],'ProfileImage_');
}
$auth_user->save();
return $this->success(data: [
'data' => UpdateProfile::make($auth_user),
], message: 'Profile updated successfully');
}
//change password
public function UpdatePassword(UpdatePassword $request){
if (!Hash::check($request->old_password, Auth::user()['password'])) {
return $this->error(message: 'Old password not matched', code: 403);
}else {
User::where('email', Auth::user()['email'])->update(['password' => bcrypt($request->new_password)]);
return $this->success(data: null, message: 'Password updated successfully');
}
}
//logout
public function Logout(Request $request){
$request->user()->currentAccessToken()->delete();
return $this->success(data: null, message: 'Logged out successfully');
}
}
6. Make a Service for Image add and update App\Services\ImageService;
<?php
namespace App\Services;
/**
* Class ImageService
* @package App\Services
*/
class ImageService
{
//Add image
public static function addImage($path, $image, $imageName) {
$filename = strtolower(
uniqid($imageName)
.'.'
.$image->getClientOriginalExtension()
);
str_replace(' ', '-', $filename);
return basename($image->move($path, $filename));
}
//update image
public static function updateImage($path, $image, $oldImage,$imageName) {
$filename = strtolower(
uniqid($imageName)
.'.'
.$image->getClientOriginalExtension()
);
str_replace(' ', '-', $filename);
$move_image = basename($image->move($path, $filename));
//delete Old Image
$image_path = public_path().'/'.$path.'/'.basename($oldImage);
if (file_exists($image_path)) {
unlink($image_path);
}
//end delete Old Image
return $move_image;
}
// Add Multiple images
public static function addMultipleImage($path, $images, $imageName) {
$imgData = [] || null;
foreach ($images as $file) {
$filename = strtolower(uniqid($imageName).'.'.$file->getClientOriginalExtension());
$file->move($path, $filename);
$imgData[] = $filename;
}
return json_encode($imgData);
}
}
7. Makes request UserRegister, LoginUser, and UpdatePassword
php artisan make:request Api/UserRegister
php artisan make:request Api/LoginUser
php artisan make:request Api/UpdatePassword
Api/UserRegister
<?php
namespace App\Http\Requests\Api;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UserRegister extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'fcm_token' => ['string'],
'password' => ['required', 'string'],
'confirm_password' => ['required', 'same:password'],
'image' => ['file', 'mimes:jpeg,png,jpg,gif,svg', 'max:2048'],
];
}
//coustom error message
public function messages()
{
return [
'name.required' => 'Name is required',
'email.required' => 'Email is required',
'password.required' => 'Password is required',
'email.unique' => 'Email already exist',
];
}
//change validation error response
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
throw new \Illuminate\Validation\ValidationException($validator, response()->json([
'message' => $validator->errors()->first(),
'data' => null,
], 422));
}
}
Api/LoginUser
<?php
namespace App\Http\Requests\Api;
use Illuminate\Foundation\Http\FormRequest;
class LoginUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
//
'email' => ['required', 'string', 'email', 'max:255'],
'password' => ['required', 'string'],
];
}
public function messages()
{
return [
'email.required' => 'Email is required',
'password.required' => 'Password is required',
];
}
//change validation error response
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
throw new \Illuminate\Validation\ValidationException($validator, response()->json([
'message' => $validator->errors()->first(),
'data' => null,
], 422));
}
}
Api/UpdatePassword
<?php
namespace App\Http\Requests\Api;
use Illuminate\Foundation\Http\FormRequest;
class UpdatePassword extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'old_password' => ['required', 'string'],
'new_password' => ['required', 'string'],
'confirm_new_password' => ['required', 'same:new_password'],
];
}
//coustom error message
public function messages()
{
return [
'old_password.required' => 'Old Password is required',
'new_password.required' => 'Password is required',
];
}
//change validation error response
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
throw new \Illuminate\Validation\ValidationException($validator, response()->json([
'message' => $validator->errors()->first(),
'data' => null,
], 422));
}
}
8. Make a Trait file for response of api App\Traits\CanResponseTrait;
<?php
namespace App\Traits;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
trait CanResponseTrait
{
/**
* The Success Response Method for API
*
* @param mixed|null $data Data to be sent
* @param string $message Message to be sent
* @param int $code Status code to be sent
* @return JsonResponse Response that will be sent
*/
protected function success(
string $message = 'success',
int $code = Response::HTTP_OK,
mixed $data = null,
): JsonResponse
{
return response()->json([
'message' => $message,
'data' => $data
], status: $code);
}
/**
* The Error Response Method for API
*
* @param mixed|null $data Data to be sent
* @param string $message Message to be sent
* @param int $code Status code to be sent
* @return JsonResponse Response that will be sent
*/
protected function error(
mixed $data = null,
string $message = 'error',
int $code = Response::HTTP_BAD_REQUEST
): JsonResponse
{
return response()->json([
'message' => $message,
'data' => $data
], status: $code);
}
/**
* The NotFound Response Method for API
*
* @param mixed|null $data Data to be sent
* @param string $message Message to be sent
* @param int $code Status code to be sent
* @return JsonResponse Response that will be sent
*/
protected function notFound(
mixed $data = null,
string $message = 'not found',
int $code = Response::HTTP_NOT_FOUND
): JsonResponse
{
return response()->json([
'message' => $message,
'data' => $data
], status: $code);
}
}
Register your Traits in your controller App\Http\Controllers\Controller.php
<?php
namespace App\Http\Controllers;
use App\Traits\CanResponseTrait;
use App\Traits\FailedValidation;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
abstract class Controller
{
//
use AuthorizesRequests, ValidatesRequests, CanResponseTrait;
} 메타데이터
- post_id
- 5962103fd704
- slug
- laravel-auth-api-standard-secure-and-scalable-authentication-solution-by-faizan-ali-5962103fd704
- url
- https://medium.com/@faizanrafique/laravel-auth-api-standard-secure-and-scalable-authentication-solution-by-faizan-ali-5962103fd704
- canonical_url
- https://medium.com/@faizanrafique/laravel-auth-api-standard-secure-and-scalable-authentication-solution-by-faizan-ali-5962103fd704
- author_url
- https://medium.com/@faizanrafique
- status
- ok
- fetched_at
- 2026-07-19 21:38:15