add cors filter for mobileapi

This commit is contained in:
Roland Schneider 2022-02-25 22:59:01 +01:00
parent 530accd8bf
commit 24d67f56d8
5 changed files with 109 additions and 15 deletions

View File

@ -53,10 +53,10 @@ class MobileDeviceManager extends BaseObject
throw new NotFoundHttpException(); throw new NotFoundHttpException();
} }
if ( // if (
in_array($device->status, [MobileDevice::STATUS_ACTIVE, MobileDevice::STATUS_INACTIVE], true) === false ){ // in_array($device->status, [MobileDevice::STATUS_ACTIVE, MobileDevice::STATUS_INACTIVE], true) === false ){
throw new NotFoundHttpException(); // throw new NotFoundHttpException();
} // }
return $device; return $device;

View File

@ -28,15 +28,15 @@
#Include conf-available/serve-cgi-bin.conf #Include conf-available/serve-cgi-bin.conf
# Always set these headers. # Always set these headers.
Header always set Access-Control-Allow-Origin "*" # Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT" # Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000" # Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token" #Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
# Added a rewrite to respond with a 200 SUCCESS on every OPTIONS request. # Added a rewrite to respond with a 200 SUCCESS on every OPTIONS request.
RewriteEngine On # RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS # RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L] # RewriteRule ^(.*)$ $1 [R=200,L]
</VirtualHost> </VirtualHost>

View File

@ -31,15 +31,16 @@ class ActivatedFilter extends ActionFilter
// get the device // get the device
/** @var MobileDevice $mobileDevice */ /** @var MobileDevice $mobileDevice */
$mobileDevice = \Yii::$app->user->getIdentity(); $mobileDevice = \Yii::$app->user->getIdentity();
$deviceId = null;
if (isset($mobileDevice)) { if (isset($mobileDevice)) {
$deviceId = $mobileDevice->id;
$idCard = $mobileDevice->id_card; $idCard = $mobileDevice->id_card;
// find out if the device is activated // find out if the device is activated
$activated = $mobileDevice->status === MobileDevice::STATUS_ACTIVE; $activated = $mobileDevice->status === MobileDevice::STATUS_ACTIVE;
} }
// if device is not activated, throw exception with http status 412 // if device is not activated, throw exception with http status 412
if ($activated === false) { if ($activated === false) {
throw new HttpException( HttpStatus::PRECONDITION_FAILED,"Device is not activated: " . $mobileDevice->id); throw new HttpException( HttpStatus::PRECONDITION_FAILED,"Device is not activated: " . $deviceId);
} }
} catch (HttpException $e) { } catch (HttpException $e) {
if ($e->statusCode === HttpStatus::PRECONDITION_FAILED && $this->isOptional($action)) { if ($e->statusCode === HttpStatus::PRECONDITION_FAILED && $this->isOptional($action)) {

View File

@ -0,0 +1,89 @@
<?php
namespace mobileapi\components;
use yii\base\Action;
use yii\base\ActionFilter;
use yii\helpers\StringHelper;
class CorsFilter extends ActionFilter
{
/**
* @var array list of action IDs that this filter will be skipped.
* Defaults to empty, meaning authentication is not skipped for any action.
* @since 2.0.7
*/
public $skip = [];
public $allowedOrigins = [
'http://localhost', 'capacitor://localhost', 'http://localhost:86'
];
private $request;
private $response;
public function beforeAction($action)
{
// if action must be skipped, do nothing
if ( $this->isSkip($action)){
return true;
}
$this->request = \Yii::$app->getRequest();
$this->response = \Yii::$app->getResponse();
$origin = $this->request->headers->get('origin');
\Yii::error("origin", $origin);
$isOriginAllowed = array_search($origin, $this->allowedOrigins, true);
if ($isOriginAllowed >= 0) {
$this->response->headers->set(
'Access-Control-Allow-Origin', $origin
);
$headers = [
'Access-Control-Allow-Headers' => 'Content-Type, content-type, Authorization, Origin',
'Access-Control-Allow-Credentials' => true,
];
foreach ($headers as $headerName => $headerValue ){
if ( $headerValue === true ){
$headerValue = 'true';
} else if ( $headerValue === false ){
$headerValue = 'false';
}
$this->response->headers->set(
$headerName, $headerValue
);
}
}
if ($this->request->isOptions && $this->request->headers->has('Access-Control-Request-Method')) {
// it is CORS preflight request, respond with 200 OK without further processing
$this->response->setStatusCode(200);
return false;
}
return true;
}
/**
* Checks, whether filter must be skipped for the given action.
*
* @param Action $action action to be checked.
* @return bool whether filter must be skipped.
* @see optional
* @since 2.0.7
*/
protected function isSkip($action)
{
$id = $this->getActionId($action);
foreach ($this->skip as $pattern) {
if (StringHelper::matchWildcard($pattern, $id)) {
return true;
}
}
return false;
}
}

View File

@ -2,12 +2,11 @@
namespace mobileapi\controllers; namespace mobileapi\controllers;
use common\models\Customer;
use common\models\MobileDevice; use common\models\MobileDevice;
use Exception; use Exception;
use Lcobucci\JWT\Token; use Lcobucci\JWT\Token;
use mobileapi\components\ActivatedFilter; use mobileapi\components\ActivatedFilter;
use mobileapi\components\CorsFilter;
use sizeg\jwt\JwtHttpBearerAuth; use sizeg\jwt\JwtHttpBearerAuth;
use Yii; use Yii;
use yii\filters\auth\AuthMethod; use yii\filters\auth\AuthMethod;
@ -28,6 +27,11 @@ class RestController extends Controller
'class' => ActivatedFilter::class, 'class' => ActivatedFilter::class,
'optional' => $this->getOptionalActivatedActions() 'optional' => $this->getOptionalActivatedActions()
]; ];
$behaviors = array_merge([ 'cors' => [
'class' => CorsFilter::class
]], $behaviors) ;
return $behaviors; return $behaviors;
} }