How to reset password via code using Laravel API
Tags: laravel, reset, password, api
Published: 2022-01-19 12:10:06

---
title: How to reset password via code using Laravel API
published: true
description: how to reset password via code using Laravel API
tags: Laravel, reset, password, api,
// cover_image: https://direct_url_to_image.jpg
---

Every Laravel project has build in the password reset process, it is working perfectly with web, but once when you come to mobile apps you going to face a problem with this way, because you make users go to web page to reset their password! & I think this not the best way to do such a thing, so the code password reset is pretty useful when you have mobile apps.

> You will find the full code with better code written at the end of post.

### Prerequisites:

• A Laravel project
• An Account in [Mailtrap](https://mailtrap.io) & get credentials and put it in `.env` file.

## Step 1: Create a new reset code table

Each Laravel project comes with `password_resets` table, I will leave this table(If your Laravel app just API for mobile apps then use password_resets) for web users and create another table for mobile apps users as follow:

1- run this command in terminal
```
 php artisan make:model ResetCodePassword -m
```
2- open `reset_code_passwords_table` migration and will be something like this:
```
Schema::create('reset_code_passwords', function (Blueprint $table) {
    $table->string('email')->index();
    $table->string('code');
    $table->timestamp('created_at')->nullable();
});
```
Now migrate the table with `php artisan migrate`.

3- open `ResetCodePassword` then fill the `$fillable` with columns names:

```
protected $fillable = [
    'email',
    'code',
    'created_at',
];
```

> Note: feel free to change anything as you need

## Step 2: Create files

- Create a new directory in `controllers` called `Api` then create these three controllers:

```
ForgotPasswordController.php   // step 1
CodeCheckController.php        // step 2
ResetPasswordController.php    // step 3
```

- Create a mail class for email:
```
php artisan make:mail SendCodeResetPassword
```

Now let's fill these files, first one  `ForgotPasswordController.php` will be something like this:

```
class ForgotPasswordController extends Controller
{
    public function __invoke(Request $request)
    {
        $data = $request->validate([
            'email' => 'required|email|exists:users',
        ]);

        // Delete all old code that user send before.
        ResetCodePassword::where('email', $request->email)->delete();

        // Generate random code
        $data['code'] = mt_rand(100000, 999999);

        // Create a new code
        $codeData = ResetCodePassword::create($data);

        // Send email to user
        Mail::to($request->email)->send(new SendCodeResetPassword($codeData->code));

        return response(['message' => trans('passwords.sent')], 200);
    }
}
```

in `CodeCheckController.php`: 

```
class CodeCheckController extends Controller
{
    public function __invoke(Request $request)
    {
        $request->validate([
            'code' => 'required|string|exists:reset_code_passwords',
        ]);

        // find the code
        $passwordReset = ResetCodePassword::firstWhere('code', $request->code);

        // check if it does not expired: the time is one hour
        if ($passwordReset->created_at > now()->addHour()) {
            $passwordReset->delete();
            return response(['message' => trans('passwords.code_is_expire')], 422);
        }

        return response([
            'code' => $passwordReset->code,
            'message' => trans('passwords.code_is_valid')
        ], 200);
    }
}
```
in `CodeCheckController.php`: 

```
class CodeCheckController extends Controller
{
    public function __invoke(Request $request)
    {
        $request->validate([
            'code' => 'required|string|exists:reset_code_passwords',
            'password' => 'required|string|min:6|confirmed',
        ]);

        // find the code
        $passwordReset = ResetCodePassword::firstWhere('code', $request->code);

        // check if it does not expired: the time is one hour
        if ($passwordReset->created_at > now()->addHour()) {
            $passwordReset->delete();
            return response(['message' => trans('passwords.code_is_expire')], 422);
        }

        // find user's email 
        $user = User::firstWhere('email', $passwordReset->email);

        // update user password
        $user->update($request->only('password'));

        // delete current code 
        $passwordReset->delete();

        return response(['message' =>'password has been successfully reset'], 200);
    }
}
```

## Step 3: Handel Mail and blade file

In `SendCodeResetPassword.php` mail:

```
class SendCodeResetPassword extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public $code;

    public function __construct($code)
    {
        $this->code = $code;
    }

    public function build()
    {
        return $this->markdown('emails.send-code-reset-password');
    }
}
```
In `send-code-reset-password.blade.php`
```
@component('mail::message')
<h1>We have received your request to reset your account password</h1>
<p>You can use the following code to recover your account:</p>

@component('mail::panel')
{{ $code }}
@endcomponent

<p>The allowed duration of the code is one hour from the time the message was sent</p>
@endcomponent
```

## Step 4: Create routes

In `routes/api.php` create links for your controllers:

```
Route::post('password/email',  ForgotPasswordController::class);
Route::post('password/code/check', CodeCheckController::class);
Route::post('password/reset', ResetPasswordController::class);
```

Now you can open postman and try these links:

```
http://your-domain.com/api/password/email       => step 1
http://your-domain.com/api/password/code/check  => step 2
http://your-domain.com/api/password/reset       => step 3
```


Source code on [Github](https://github.com/RabeeaAli/code-reset-password)