Hi All,
I have been searching the internet for the past week for a bug that I’m currently experiencing, and no luck. the best description that I can find is this one.
(Add handleOptions to Cors filter so OPTIONS requests are handled for the preflight check. #14618).
I’m using angular2 to make a post request to a Yii2 Rest API, the problem that I’m expereining is that the browser send an OPTIONS request first and when it does that , YII2 doesn’t know how to handle it and send back 401 error with a preflight
Request URL:http://localhost/analytic/backend/web/v1/api/test
Request Method:OPTIONS
Status Code:401 Unauthorized
Remote Address:[::1]:80
Referrer Policy:no-referrer-when-downgrade
Response Headers
view parsed
zone.js:2744 OPTIONS http://localhost/analytic/backend/web/v1/api/test 401 (Unauthorized)
dashboard:1 Failed to load http://localhost/analytic/backend/web/v1/api/test: Response for preflight has invalid HTTP status code 401
I looked at the Yii2 documentation and have implemented CORS as follow.
use yii\rest\Controller;
use yii\filters\auth\HttpBearerAuth;
/**
* Site controller
*/
class ApiController extends Controller
{
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator'] = [
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
];
// remove authentication filter
$auth = $behaviors['authenticator'];
unset($behaviors['authenticator']);
// add CORS filter
$behaviors['corsFilter'] = [
'class' => \yii\filters\Cors::className(),
];
// re-add authentication filter
$behaviors['authenticator'] = $auth;
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
$behaviors['authenticator']['except'] = ['options'];
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
];
return $behaviors;
}
}
I am able to authenticate fine if I commented out ‘HttpBearerAuth::className()’ do a post through angular, then uncomment that line then do another post.
example.
// $behaviors['authenticator'] = [
// 'class' => HttpBearerAuth::className(),
// ];
Post through angular, then uncomment those lines.
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
];
the reason why it works when I do that is that the browser sends all following request as POST and not OPTIONS.
Moreover, when I perform the same request with POSTMAN, it works fine with no issues and that’s because POSTMAN sends it as a POST request.
Any help is appreciated. thank you