Yii2 bug with CORS when not valid access token - rest

I did with yii2 an acess token authorization if the access token is valid it works fine, but if the access token is invalid it returns the following CORS problem
Access to XMLHttpRequest at 'server' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
if the token is expired, the server works fine storing the old token on another table etc, but the client still gets the same CORS problem
I don't understand why it only happens when I try to return a 401 response, but it works when the acces token is valid, any idea?
This is the code I think its relevant
BehaviorsConfig.php
public static function corsFilterConfig($metodos_aceptados)
{
return [
'class' => Cors::className(),
'cors' => [
'Origin' => ['*'],
'Access-Control-Allow-Origin' => ['*'], // Añadido
'Access-Control-Request-Method' => $metodos_aceptados,
'Access-Control-Request-Headers' => ['*'],
'Access-Control-Allow-Credentials' => false,
'Access-Control-Max-Age' => 86400,
],
];
}
public static function authenticatorConfig()
{
return [
'class' => QueryParamAuth::className(),
'except' => ['options'],
'tokenParam' => 'access_token',
];
}
every controller
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['corsFilter'] = BehaviorsConfig::corsFilterConfig(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']);
$behaviors['authenticator'] = BehaviorsConfig::authenticatorConfig();
return $behaviors;
}
and now to check if the token is still valid and not expired I did this function
public function beforeAction($action){
if(AccessService::isExpired()){
throw new HttpException(401, "Sesión expirada, vuelva a conectarse.");
}
if (!parent::beforeAction($action)) {
return false;
}
return true;
}

Related

Symfony HttpClient, fail to authenticate external API witch Bearer

I have a problem, I try to use a external API, but the response of that APi is a 401.
1º- I send a request to get the auth token, works fine.
$auth = $this->client->request(
'POST',
'https://api.namebright.com/auth/token',
[
'body' => [
'grant_type' => 'client_credentials',
'client_id' => $clientID,
'client_secret' => $clientSecret,
],
]
);
2º- handler token, i dump the token is loocks fine
$token = sprintf('Bearer %s', $auth->toArray()['access_token']);
3º- I make other request to get the API response, i got a 401.
$response = $this->client->request(
'GET',
'http://api.namebright.com/rest/purchase/availability/google.pt',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => $token,
],
]
);
I don't know what i'm doing wrong. :(
I checked, for responses on the internet and i don't see the problem.
I Tried to change Authorization to authorization.
I tried to check the token in the postmen, works fine.

Laravel redirect to a named route with param returns status 200

I have the following named route with params, to which I want to redirect from a post request:
Route::get('/view-project-team/{project_request_id}', 'SinglePageController#viewProjectTeam')->name('view.project.team');
The controller where I handle the post request:
public function createProjectTeam(Request $request){
try {
$projectRequest = ProjectRequest::create(['project_title' => $request->projectTitle]);
TeamMember::whereIn('email', $request->projectTeamEmails)
->update([
'project_request_id' => $projectRequest->id
]);
$projectTeam = TeamMember::get();
/*return response()->json( [
'success'=> true,
'projectRequestId' => $projectRequest->id
]);*/
return redirect()->route('view.project.team', ['project_request_id' => $projectRequest->id ]);
} catch(\Exception $e){
return ['success' => false, 'message' => 'project team creation failed'];
}
}
And the response that I get:
In the network tab, I see 90 under Name, which obviously stands for the id and only when I hover over I see the full URL http://team-management-tool.test/view-project-team/90
It is so weird as it seems correct the way i use the redirect, no clue what can be the issue then?

Stop sending the access token with the response body in Yii2

I am developing a rest API using Yii2, the front end is developed by ionic.
the case is that when I have an action which it uses bearer authentication..
it works fine but the access token is returned with the response body which leads to an HttpErrorResponse in the client side:
SyntaxError: Unexpected token y in JSON at position 0 at Json.parse
the response is returned like this so the client is not able to parse the json
y2sSCEXqkUoVY2BjkQZqx8g3W42273Cz{"success":false,"message":"you liked it before"}
this is the behaviour code which uses the bearear authentication
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' => CorsCustom::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' => CompositeAuth::className(),
'only' => ['like', 'unlike', 'likes', 'create'],
'authMethods' => [
HttpBearerAuth::className(),
],
];
return $behaviors;
}
I want to stop sending the access token in the body or send it as a json
I think you should remove the echo $token statement from your USER model
public static function findIdentityByAccessToken($token, $type = null)
{
/* echo $token; */
return static::findOne(['auth_key' => $token]);
}
Stop echo the token before the response and you'll get your job DONE!
public static function findIdentityByAccessToken($token, $type = null)
{
/* echo $token; */
return static::findOne(['auth_key' => $token]);
}

Yii2 Cross-Origin Request Blocked WITH ANGULAR2

Am using angular2 and yii2 restful services but it fails
In yii2 controller i have set
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['corsFilter'] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to
'Origin' => ['http://localhost:4200'], //this is my angular2 source
'Access-Control-Request-Method' => ['POST', 'GET','PUT', 'OPTIONS'],
// Allow only POST and PUT methods
'Access-Control-Request-Headers' => ['*'],
// Allow only headers 'X-Wsse'
// 'Access-Control-Allow-Credentials' => true,
// Allow OPTIONS caching
'Access-Control-Max-Age' => 3600,
// Allow the X-Pagination-Current-Page header to be exposed to the browser.
'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
],
];
$auth = $behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
'only' => ['can-access','profile'], //access controller
];
$behaviors['authenticator']['except'] = ['options'];
return $behaviors;
}
In angular2 am setting the headers as
get(url) {
let headers = new Headers();
let token = JSON.parse(localStorage.getItem("currentUser")).token;
if (token) {
headers.append('Authorization', 'Bearer ' + token);
headers.append('Content-Type', 'application/x-www-form-urlencoded');
}
let options = new RequestOptions({ headers: headers });
return this.http.get(url, {headers:headers});
}
when i check a post request am getting an error that
Cross-Origin Request Blocked: The Same Origin Policy disallows
reading the remote resource at
http://127.0.0.1/bcl/api/rest/v1/users/profile.
(Reason: CORS preflight channel did not succeed).
Internet search i found out that i needed to set the cors filters as above but still it fails
As your error states, the browser sent a preflight request, got a list of allowed Origins( in your case it is 'http://localhost:4200') and devided to block your request.
Your request is at "http://127.0.0.1/bcl/api/rest/v1/users/profile" when your Allowed origin is set to "http://localhost:4200".
Change
'Origin' => ['http://localhost:4200'],
to
'Origin' => ['http://127.0.0.1'],
'Origin' => ['http://localhost:4200'],
to
'Origin' => ['*'],

Validation error messages as JSON in Laravel 5.3 REST

My app is creating a new entry via a POST request in an api end point.
Now, if any validation is failed then instead of returning an error json, laravel 5.3 is redirecting the request to home page.
Here is my controller:
public function create( Request $request )
{
$organization = new Organization;
// Validate user input
$this->validate($request, [
'organizationName' => 'required',
'organizationType' => 'required',
'companyStreet' => 'required'
]);
// Add data
$organization->organizationName = $request->input('organizationName');
$organization->organizationType = $request->input('organizationType');
$organization->companyStreet = $request->input('companyStreet');
$organization->save();
return response()->json($organization);
}
If there is no issue with validation then the entity will be successfully added in the database, but if there is issue with validating the request then instead of sending all the error messages as a json response it redirects back to the home page.
How i can set the validate return type to json, so with every request if the validation failed then laravel will send all the error messages as json by default.
You can do your validation as:
$validator = \Validator::make($request->all(), [
'organizationName' => 'required',
'organizationType' => 'required',
'companyStreet' => 'required'
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422)
}
The validation used in the question looks as per the recommendation by laravel. The reason of redirection is that it throws an exception which you can easily catch using the code below. So it's better to use the recommended way of code instead of re-writing framework's code again :)
public function create( Request $request )
{
$organization = new Organization;
// Validate user input
try {
$this->validate($request, [
'organizationName' => 'required',
'organizationType' => 'required',
'companyStreet' => 'required'
]);
} catch (ValidationException $e) {
return response()->json($e->validator->errors(), 422);
}
// Add data
$organization->organizationName = $request->input('organizationName');
$organization->organizationType = $request->input('organizationType');
$organization->companyStreet = $request->input('companyStreet');
$organization->save();
return response()->json($organization, 201);
}