Search code examples
phplaravelauthenticationlaravel-middleware

Laravel route not calling function of controller after adding auth middleware


After adding the auth:api middleware, my route suddenly stops calling the function it is supposed to. When I remove the middleware, it starts working again.

api.php route

Route::middleware('auth:api')->get('/addloancontroller', [\App\Http\Controllers\AddLoan::class, 'store'])
    ->name('addLoan');

AddLoan.php Controller

<?php

namespace App\Http\Controllers;

use App\Models\EarningsRecord;
use App\Models\Lender;
use App\Models\LoanLenders;
use App\Models\Loans;
use App\Models\Login;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Auth;
use Illuminate\Support\Facades\DB;

class AddLoan extends Controller
{
    public function store(Request $request) {

        $request->validate([
            'amount' => 'required',
            'startDate' => 'required',
            'endDate' => 'required',
            'dateLoanSigned' => 'required',
            'interestRate' => 'required',
            'interestPaymentPeriod' => 'required',
            'interest_only_period' => 'required',
            'active' => 'required',
            'loanType' => 'required',
            'fName' => 'required',
            'lName' => 'required',
            'earnings' => 'required',
            'irdNum' => 'required',
            'bankAccNum' => 'required',
            'address' => 'required',
            'phone' => 'required',
        ]);

        $company_id = $request->user();
        dd($company_id);

        $loan = Loans::create([
            'companies_id' => $company_id,
            'amount' => $request->amount,
            'startDate' => $request->startDate,
            'endDate' => $request->endDate,
            'dateCreated' => $request->dateLoanSigned,
            'interestRate' => $request->interestRate,
            'interestPaymentPeriod' => $request->interestPaymentPeriod,
            'interestOnlyPeriod' => $request->interestOnlyPeriod,
            'active' => $request->active,
            'refinanced' => 0,
            'loanType' => $request->loanType
        ]);

        $loan->save();


        $lender = Lender::create([
            'fName' => $request->fName,
            'lName' => $request->lName,
            'annualEarnings' => $request->earnings,
            'irdNum' => $request->irdNum,
            'bankAccNum' => $request-> bankAccNum,
            'address' => $request-> address,
            'phone' => $request->phone,
            'loginID' => null
        ]);

        $lender->save();

        $taxAmount = DB::table('tax_rates')
                        ->where('minAmount', '<', $request->earnings)
                        ->where('maxAmount', '>', $request->earnings);

        $loanLender = LoanLenders::create([
            'loansID' => $loan->id,
            'lenderID' => $lender->id,
            'companyID' => $company_id,
            'taxAmount' => $taxAmount->id
        ]);

        $loanLender->save();

        $earningsReport = EarningsRecord::create([
            'lenderID' => $lender->id,
            'annualEarnings' => $lender->annualEarnings,
            'dateRecorded' => date('d-m-Y')
        ]);

        $earningsReport->save();

        return redirect(RouteServiceProvider::HOME);
    }
}

The route is called as a action in a form:

<form method="GET" action="{{ route('addLoan') }}">

The reason all of my validation is just looking for 'required' is because I wanted to make sure it wasn't validation failing and just not producing a error.

What happens when I submit the form?

When I submit the form and the route has the middleware attached to it, it simply redirects me back to the home screen.

Cache

I have already run:

  • php artisan cache:clear
  • composer dump-autoload

Authentication Token

As explained in the laravel documentation, I have already added the api_token column to the migration file for the User (in my case, I use the Login model for authentication). Below is the line in the migration file where I add that column:

$table->string('api_token', 80)->unique()->nullable()->default(null);

This is the line in the documentation:

Schema::table('users', function ($table) {
    $table->string('api_token', 80)->after('password')
                        ->unique()
                        ->nullable()
                        ->default(null);
});

When I create the model object, I make the authenticated token by doing so:

'api_token' => Str::random(60)

When I check the database, I see that the api_token successfully has been added so I not sure to what the issue could be.

(The documentation link I used is here)


Solution

  • You have defined a route in your api routes file and protected it with the auth:api middleware (which is commonly Passport), yet you are calling the route from an HTML form which is not how you would typically consume an api.

    I assume you're just looking to protect routes accessed via web pages within your application, therefore I suggest you research one of the web based authentication mechanisms for Laravel such as Fortify or if you don't want to roll your own views, either Jetstream or Breeze.

    Update

    Tokens are used in conjunction with an api, the workflow you've currently implemented (a web form) is a web workflow so using api tokens is not recommended.

    The Auth facade is available in controller as long as a user is authenticated and works for both the web and api guards.

    If you install either Breeze or Jetstream, which I would recommend over Fortify if you're just starting out, you will be able to use the auth middleware to protect your routes requiring users to authenticate themselves (login) in order to access a protected route. This then means that when a user has authenticated and you process a request in your controller Auth::id() will return the id of the authenticated user.