Skip to content
Advertisement

Laravel 8 password confirm middleware usage as API doesn’t return a URL for redirection

I’m working inside a Laravel 8 project used as a REST API for a Nuxt JS front-end. I’d like to be able to require the user to confirm their password for some important actions, so in one of my controller’s am using the Laravel middleware for password.confirm but this is just returning a message to confirm a password, I’m not given any route, I’ll need to build a page in my site, and redirect the user there.

What do I need to change in my update method to support this?

<?php

namespace AppHttpControllersAccount;

use IlluminateValidationRule;
use IlluminateSupportStr;
use IlluminateSupportFacadesAuth;
use IlluminateSupportFacadesHash;
use IlluminateSupportFacadesValidator;
use AppHttpControllersController;
use IlluminateHttpRequest;
use AppModelsBrand;
use CarbonCarbon;

class BrandController extends Controller
{
    /**
     * Instantiate a new BrandController instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:sanctum');

        $this->middleware('password.confirm', [
            'only' => ['update']
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateHttpResponse
     */
    public function update(Request $request, $slug)
    {
        $validator = Validator::make($request->all(), [
            'brand' => 'required|string',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => "One or more fields has been missed or is invalid.",
                'errors' => $validator->messages()
            ], 400);
        }

        // TODO: confirm password...

        $brand = Brand::where('user_id', Auth::id())
                      ->where('slug', $slug)
                      ->first();

        if (!$brand) {
            return response()->json([
                'message' => "We can't find this brand"
            ], 404);
        }

        try {
            
            $brand->save();

            return response()->json([
                'message' => "Your brand has been updated",
                'brand' => $brand ?? null
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'message' => "We weren't able to update this brand right now."
            ], 422);
        }
    }
}

Advertisement

Answer

You don’t need a middleware to implement that, just asks the user’s password before submitting the request and include it on your payload.

Then on your update method, you can simply apply a validation like this

public function update(Request $request, $slug) {

    $request->validate([
        'brand' => 'required|string',
        'password' => 'required|password:api'
    ],[
        'brand.required' => 'You need to specify the brand',
        'password.required' => 'You need to provide a password to perform this request',
        'password.password' => 'The password you have provided is incorrect!'
    ]);

    // All ok, Continue update
    ...
    ...
}

there’s a password validation implemented I think since laravel 6, where it checks the input value and compare it with the current authenticated user password.

Also, when you call validate function, it automatically throws back an error if there’s any failure so you don’t need to manually check if it fails and manually return something.

e.g. if your the password in your payload does not match the current authenticated user password, you’ll get a response like this.

{
    "message": "The given data was invalid.",
    "errors": {
        "password": ["The password you have provided is incorrect!"]
    }
}
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement