2

I'm having an odd problem with CORS in Laravel that I've struggled with for over a day now. It's different from the other posts I've seen about the laravel-cors package such as this one: Laravel angularJS CORS using barryvdh/laravel-cors

I've setup the package according to the instructions, and the only other addition to Laravel I've made is a package for JWT.

What is happening is that CORS is only working in POST requests. I can use POSTMAN to hit my authenticate route and everything looks good, but as soon as I try any GET request no CORS headers are being sent. I've tried moving different controllers to my 'unprotected' routes to remove the possibility that JWT is interfering but this doesn't change anything.

Here is my routes.php:

<?php

// unprotected routes
Route::group(['prefix' => 'api/v1', 'middleware' => 'cors'], function () {
  Route::post('authenticate', 'AuthenticateController@authenticate');
  Route::resource('trips', 'TripController'); // moved to unprotected to test CORS
});

// protected routes
Route::group(['prefix' => 'api/v1', 'middleware' => ['cors', 'jwt.auth']], function () {
  Route::get('authenticate/user', 'AuthenticateController@getAuthenticatedUser');
  Route::resource('airports', 'AirportController');

});

And my cors.php:

<?php
return [
    /*
     |--------------------------------------------------------------------------
     | Laravel CORS
     |--------------------------------------------------------------------------
     |
     | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
     | to accept any value, the allowed methods however have to be explicitly listed.
     |
     */
    'supportsCredentials' => true,
    'allowedOrigins' => ['*'],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['GET', 'POST', 'PUT', 'OPTIONS',  'DELETE'],
    'exposedHeaders' => [],
    'maxAge' => 0,
    'hosts' => [],
];

And one of my controllers:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;

class AuthenticateController extends Controller
{
    public function authenticate(Request $request)
    {
        $credentials = $request->only('email', 'password');

        try {
            // verify the credentials and create a token for the user
            if (!$token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            // something went wrong
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        // if no errors are encountered we can return a JWT
        return response()->json(compact('token'));
    }

    public function getAuthenticatedUser()
    {
        try {
            if (!$user = JWTAuth::parseToken()->authenticate()) {
                return response()->json(['user_not_found'], 404);
            }
        } catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
            return response()->json(['token_expired'], $e->getStatusCode());
        } catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
            return response()->json(['token_invalid'], $e->getStatusCode());
        } catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
            return response()->json(['token_absent'], $e->getStatusCode());
        }

        // the token is valid and we have found the user via the sub claim
        return response()->json(compact('user'));
    }
}
Community
  • 1
  • 1
Graham
  • 162
  • 1
  • 12
  • I suggest you to implement a cors middleware by yourself instead of using barryvdh/laravel-cors. If you are interested let me know and I will post it as an answer. – Alex Kyriakidis Jul 12 '15 at 14:03
  • I was looking at doing that, I figured not it's not just as simple as setting access to '*', I've learned you need to account for the "preflight" request. Looking forward to an answer. – Graham Jul 12 '15 at 15:45

1 Answers1

0

Exclude your route group from CSRF protection. app/Http/Middleware/VerifyCsrfToken.php

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

;)

Pablo.mtz
  • 152
  • 3
  • 11