Reputation: 176
I'm experiencing CORS-related issues when making requests to my Slim PHP API from my Angular application. I'm getting the following error message in the console:
Error from client log console: XHROPTIONS http://localhost:8080/api/validate CORS Missing Allow Credentials
Bloccata richiesta multiorigine (cross-origin): il criterio di corrispondenza dell’origine non consente la lettura della risorsa remota da http://localhost:8080/api/validate. Motivo: previsto “true” in header CORS “Access-Control-Allow-Credentials”.
Bloccata richiesta multiorigine (cross-origin): il criterio di corrispondenza dell’origine non consente la lettura della risorsa remota da http://localhost:8080/api/validate. Motivo: richiesta CORS non riuscita. Codice di stato: (null). Http failure response for http://localhost:8080/api/validate: 0 Unknown Error
Here is my middleware code:
php
$fitnetApi->slim->add(function (Request $request, Response $response, callable $next) {
$uri = $request->getUri()->getPath();
// Controlla se l'URI inizia con '/api'
if (strpos($uri, '/api') === 0) {
$cookies = $request->getCookieParams();
$token = $cookies['jwt_token'] ?? null; // Usa l'operatore null coalescing
// Se non c'è un token, continua con il middleware successivo
if (!$token) {
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "token invalid"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
try {
// Decodifica il token
$decoded = JWT::decode($token, new Key('', 'HS256'));
// Controlla se il token è scaduto
if (isset($decoded->exp) && $decoded->exp < time()) {
$rtoken = $cookies['rjwt_token'] ?? null;;
$decRjwt = JWT::decode($rtoken, new Key('', 'HS256'));
// Controlla se il rtoken esiste e non è scaduto
if ($decRjwt && isset($decRjwt->exp) && $decRjwt->exp > time()) {
// Rigenera un token
$newToken = JWT::encode(
[
'id' => $decoded->id,
'type' => $decoded->type,
'exp' => time() + 60 * 15 // 15 minuti
],
"",
"HS256"
);
// Aggiunge il nuovo token come attributo alla richiesta
$request = $request->withAttribute('new_token', $newToken);
} else {
// Se il rtoken è scaduto, restituisci un errore
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "rtoken expired, renew auth"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
}
} catch (ExpiredException $e) {
// Gestisci il caso in cui il token JWT è scaduto
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "Token expired"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
} catch (SignatureInvalidException $e) {
// Gestisci il caso in cui il token JWT è invalido
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "Invalid token signature"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
} catch (\Exception $e) {
// Gestione generica di eccezioni JWT
return $response
->withHeader("Content-Type", "application/json")
->withStatus(401)
->write(json_encode([
"status" => "error",
"message" => "Invalid token"
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
}
// Continua con il prossimo middleware o la route
return $next($request, $response);
});
cors settings in middleware:
$fitnetApi->slim->add(new Tuupola\Middleware\CorsMiddleware([
"origin" => ["http://localhost:8100"],
"methods" => ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
"headers.allow" => ["Token", "Authorization", "If-Match", "If-Unmodified-Since", "Content-Type"],
"headers.expose" => ["Authorization"],
"credentials" => true,
"cache" => 0,
]));
The error occurs when making a POST request to http://localhost:8080/api/validate. Despite the CORS headers being set, I still receive an "Unknown Error" with a status of 0.
I've verified that the backend is running on localhost:8080. The API responds correctly to requests made through Postman. I've checked for JavaScript errors in the Angular application.
What could be causing these CORS issues, and how can I fix the error so that my Angular application can communicate with the Slim PHP API successfully?
Any help would be appreciated!
Upvotes: 3
Views: 174
Reputation: 26
I've never used Slim, but I think the header(Access-Control-Allow-Origin) is probably getting overridden with a diff port in the middleware later in the code that you have shared(see line 43). Also you seems to have missed one line that I've added below.
So the closure code should probably start something like this:
$fitnetApi->slim->add(function (Request $request, Response $response, callable $next) {
$uri = $request->getUri()->getPath();
$res = $next($req, $res); // you forgot this line
// Imposta gli header CORS
$res = $res
->withHeader('Access-Control-Allow-Origin', 'http://localhost:8100') // Cambia con l'URL del frontend
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->withHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type')
->withHeader('Access-Control-Allow-Credentials', 'true');
// Gestisci le richieste OPTIONS
if ($request->getMethod() === 'OPTIONS') {
return $response;
}
// Prosegui solo se l'URI inizia con '/api'
if (strpos($uri, '/api') === 0) {
$cookies = $request->getCookieParams();
$token = $cookies['jwt_token'] ?? null;
If that did not work, try this
$res = $res->withHeader('Access-Control-Allow-Origin', '*');
Upvotes: 0
Reputation: 45
I'd like to point out that in your Tuupola\Middleware\CorsMiddleware
instance you indicated as origin http://localhost:8100
but your are on port 8080
so that could be a starting point.
if this doesn't work I suggest lazy CORS handling, as indicated in slim doc, here's an example:
return $response
->withHeader('Access-Control-Allow-Origin', 'http://localhost:8080')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
Upvotes: 0
Reputation: 893
you need to handle OPTIONS Requests in Slim by adding the handler seperately
$app->options('/{routes:.+}', function ($request, $response, $args) {
return $response;
});
Refer : https://www.slimframework.com/docs/v3/cookbook/enable-cors.html
you can also try adding CORS header directly in Apache ,
try adding this to .htaccess
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "http://localhost:8100"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Token, Authorization, If-Match, If-Unmodified-Since, Content-Type"
Header always set Access-Control-Allow-Credentials "true"
</IfModule>
Upvotes: 3