User Registration with OTP Email Verification
A secure and modern user registration system where users must verify their email address using a One-Time Password (OTP). This ensures authenticity, prevents fake accounts, and enhances overall platform security.
Key Benefits
Prevents spam and fraudulent registrations
Confirms email ownership before account activation
Improves trust and compliance
Login with Secure Credential Validation
Users can log in only after successful email verification. Credentials are securely validated using Laravel’s hashing and token-based authentication.
OTP-Based Password Reset via Email
A robust password recovery workflow that sends a time-limited OTP to the user’s registered email address, ensuring secure identity verification before resetting the password.
Send & Verify OTP for Password Reset
OTP codes are:
Randomly generated
Time-bound
Single-use
Securely stored and validated
Password Change with OTP Verification
Users can update their password only after successful OTP verification, protecting against unauthorized access.
Email Verification Code System
An independent OTP verification mechanism that can be reused for:
Email verification
Password reset
Sensitive account actions
Resend OTP Verification Code
Allows users to request a new OTP if the previous one expires, with rate limiting to prevent abuse.
Secure Forgot Password Workflow
A complete, user-friendly, and secure password recovery system following industry best practices.
User Role Assignment System
Each user can be assigned one or multiple roles (Admin, Manager, User, etc.), defining their access level.
Create, Edit & Delete User Roles
Admins can dynamically manage roles without modifying application code.
Dynamic Role-Based Access Control (RBAC)
Permissions are enforced at:
API level
Controller level
Middleware level
Ensuring secure and scalable authorization.
Permission Management for User Actions
Each permission represents a specific action such as:
Create User
Edit User
Delete User
View Reports
Assign Permissions to Roles
Roles act as permission containers, making authorization management simple and efficient.
View Role-Permission Matrix
Admins can visually inspect which permissions belong to which roles.
Activate or Deactivate Roles
Temporarily disable roles without deleting them, ensuring operational flexibility.
Admin Panel for Managing Roles & Permissions
A centralized admin interface to control access policies with full auditability.
app/ ├── Models/ │ ├── User.php │ ├── Role.php │ ├── Permission.php │ └── Otp.php ├── Http/ │ ├── Controllers/ │ │ ├── AuthController.php │ │ ├── OtpController.php │ │ └── RoleController.php │ ├── Middleware/ │ │ └── CheckPermission.php ├── Mail/ │ └── SendOtpMail.php database/ ├── migrations/ routes/ └── api.php
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->boolean('status')->default(true);
$table->timestamps();
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('code');
$table->string('type'); // email_verification | password_reset
$table->timestamp('expires_at');
$table->timestamps();
$table->id();
$table->string('name')->unique();
$table->boolean('is_active')->default(true);
$table->timestamps();
$table->id();
$table->string('name')->unique();
$table->timestamps();
$table->foreignId('role_id');
$table->foreignId('permission_id');
$table->foreignId('user_id');
$table->foreignId('role_id');
function generateOtp()
{
return random_int(100000, 999999);
}
class SendOtpMail extends Mailable
{
public function __construct(public string $otp) {}
public function build()
{
return $this->subject('Your Verification Code')
->view('emails.otp')
->with(['otp' => $this->otp]);
}
}
public function register(Request $request)
{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
$otp = generateOtp();
Otp::create([
'user_id' => $user->id,
'code' => $otp,
'type' => 'email_verification',
'expires_at' => now()->addMinutes(10),
]);
Mail::to($user->email)->send(new SendOtpMail($otp));
return response()->json([
'message' => 'Registration successful. OTP sent to email.'
]);
}
public function verifyEmail(Request $request)
{
$otp = Otp::where('code', $request->otp)
->where('type', 'email_verification')
->where('expires_at', '>', now())
->firstOrFail();
$otp->user->update(['email_verified_at' => now()]);
$otp->delete();
return response()->json(['message' => 'Email verified successfully']);
}
public function resetPassword(Request $request)
{
$otp = Otp::where('code', $request->otp)
->where('type', 'password_reset')
->firstOrFail();
$otp->user->update([
'password' => bcrypt($request->password)
]);
$otp->delete();
return response()->json(['message' => 'Password reset successful']);
}
public function handle($request, Closure $next, $permission)
{
if (!$request->user()->hasPermission($permission)) {
return response()->json(['message' => 'Unauthorized'], 403);
}
return $next($request);
}