0

I'm logged into my website and the page I'm currently on requires the admin middleware. I've also got an api call I'm making from this page. This api call is also going through the same admin middleware and is in the api.php file (laravel 5.3). My requests to the web page works. However my middleware on the api call returns a 302 redirecting me to the login page. My test case for this api call with Auth::actingas($user) works fine as well. The middleware does not seem to recognize that I am logged in even though the page does.

I've also added api/* to the exceptions list in VerifyCSRF. How can I fix this?

Here's my routes/web.php file (the page I'm currently on is manageAdmins:

Route::group(['prefix' => 'admin', 'middleware' => ['admin']], function(){
  Route::get('/', 'AdminController@showHome');
  Route::get('categories', 'AdminController@showCategories');
  Route::get('categories/add', 'AdminController@getAddCategories');
  Route::get('manageAdmins', 'AdminController@manageAdmins');

});

My routes/api.php file:

<?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:api');

Route::get('categories/{id}/children', 'CategoryController@getChildren');

Route::group(['prefix' => 'admin', 'middleware' => ['web', 'admin']], function() {
    Route::put('makeNormalUserOfAdmin/{id}', 'AdminController@makeNormalUserOfAdmin');
});

Here's the api call the admin middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Auth;

class Admin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $guard=null)
    {
        if (!(Auth::guard($guard)->check())) {
          return redirect('/login');
        }
        if(!(Auth::user()->is_admin)){
            return redirect('/home');
        }
        return $next($request);
    }
}

Here is the api call that's failing:

/**
 * delete an admin from the database
 */
function deleteAdmin(id){
    $.ajax({
        method: "PUT",
        url: "/api/admin/makeNormalUserOfAdmin/" + id,
        error: function(data){
            alert('error');
        },
        success: function(data){
            $("table#admins tr#id" + id).fadeOut();
        }
    });
}

and Finally here is the test case that is passing:

<?php

use Illuminate\Foundation\Testing\DatabaseMigrations;
use App\User;

class MakeNormalUserOfAdminTest extends TestCase
{
    use DatabaseMigrations;

    /**
     * Test the get categories method
     *
     *
     */
    public function testMakeNormalUserOfAdmin()
    {

        $miscalaneousUsers = factory(App\User::class, 20)->create();

        $user = factory(App\User::class)->create([
            'is_admin' => true
        ]);

        $this->actingAs($user)
            ->json("PUT", "api/admin/makeNormalUserOfAdmin/$user->id")
            ->assertResponseOk()
            ->assertResponseStatus(200);

        $this->seeInDatabase('users', [
            'id' => $user->id,
            'name' => $user->name,
            'password' => $user->password,
            'remember_token' => $user->remember_token,
            'updated_at' => $user->updated_at,
            'created_at' => $user->created_at,
            'is_admin' =>  0
        ]);

        $this->dontSeeInDatabase('users', [
            'is_admin' => 1
        ]);

    }
}
Jake Sylvestre
  • 936
  • 3
  • 14
  • 39

1 Answers1

0

PHP does not handle PUT requests, so laravel mimics it by sending POST with _method=put body field. So, in order for your request to work you need to add data

data: {
    _token: csrfToken,
    _method: 'put'
}

And change request method to POST

Skysplit
  • 1,875
  • 12
  • 16