baguus

web and api authentication middleware

Posted 1 year ago by baguus

Hi everyone. sorry for the "undefined" title. I don't know how to phrase is correctly. I have a view in my app that is accessible to authenticated users.

web.php

Route::get('/orders/complete', [
    'as' => 'completeOrders', 'uses' => '[email protected]']);

OrdersController.php

    public function completeOrders(Request $request)
    {
        if (!Auth::check()) {
            return redirect('/');
        }
        $request->user()->authorizeRoles(['admin']);

        $orders = Order::CompleteOrders(AppHelper::instance()->getCurrentSeason())->get();
        return view('orders.complete', compact('orders'));
    }

View

<meta name="csrf-token" content="{{ csrf_token() }}"/>

<table id="completeorders">
    <thead>
            <tr>
                    <th>Order ID</th>
            <th>Country</th>
            <th>Company name</th>
            <th class="check">Confirmed</th>
            <th>View</th>
        </tr>
    </thead>
    <tbody>
    @foreach ($orders as $order)
        <tr>
            <td>{{ $order->id}}</td>
            <td>{{ $order->country }}</td>
            <td>{{ $order->name }}</td>
            <td>{{ Form::checkbox($order->id, $order->id, $order->confirmed, ['class' => 'checkbox fa-fw', 'id' => $order->id]) }} </td>
            <td><a href="{{ url('orders/cartcomplete/' . $order->id) }}"><i
                                                class="fa fa-search fa-fw"></i></a></td>
        </tr>
    @endforeach 
    </tbody>
</table>

my.js

$(document).ready(function () {

$('#completeorders').on('click', 'input[type="checkbox"]', function (e) {

        var isChecked = $(this).is(':checked');
        e.preventDefault();
        
        var checked = '';
        var dataId = $(this).val();
        var myid = "#" + dataId;

        var url = window.location.protocol + "//" + window.location.host + "/" + 'api/orders/complete';
        var token = $('meta[name="csrf-token"]').attr('content');
        
    $('html, body').css("cursor", "wait");
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        $.ajax({
            type: 'POST',
            url: url,
            dataType: 'JSON',
            data: {
                "_method": 'POST',
                "_token": token,
                "id": dataId,
                "isChecked": isChecked
            },
            context: this,
            success: function (response) {
                console.log('success');
        console.log(response[0].successful);
        $(this).prop("checked", isChecked);
                $('html, body').css("cursor", "auto");
            },
            error: function (e) {
              //  console.log(e.responseText);
                $(this).prop("checked", !isChecked);
        $('html, body').css("cursor", "auto");
            }
        });
    });

});

Kernel.php

 protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
        //    \Illuminate\Session\Middleware\AuthenticateSession::class,
        //    \App\Http\Middleware\VerifyCsrfToken::class,
            'throttle:60,1',
            'bindings',

        ],
    ];


    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'admin' => \App\Http\Middleware\Admin::class, 
        'ajax' => \App\Http\Middleware\AllowOnlyAjaxRequests::class,
    ];

VerifyCsrfToken.php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        //   'ajax/*',
    ];

    protected function tokensMatch($request)
    {
        $token = $request->ajax() ? $request->header('X-CSRF-Token') : $request->input('_token');
        return $request->session()->token() == $token;
    }
}

api.php

Route::post('orders/complete', '[email protected]');

ConfirmatonController.php

 public function confirm(Request $request) {

return response()->json(array(['successful' => 'Response ok!']));

So up to here the api call works but is not verified.

How do I verify/authenticate this api call?

If I change my api.php to

Route::group(['middleware' => ['web']], function () {
    Route::post('orders/complete', '[email protected]');
});

i get 408 TokenMismatchException

How can I verify this correctly. I want to allow the post call only if the user is logged in.

Please sign in or create an account to participate in this conversation.

Reply to

Use Markdown with GitHub-flavored code blocks.