Verbs for custom action is not working in yii2 REST API - php

i'm adding a verb to the verbs behaviors to only allow POST request for some action and if the request not a POST it should return method not allowed but this is not working it return 404 not found response not 405 Not allowed response when i'm sending a GET request instead of POST please any help
i set in my REST control the behaviors like this
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'except' => ['login'],
'authMethods' => [
HttpBearerAuth::className(),
],
];
$behaviors['verbs'] = [
'class' => \yii\filters\VerbFilter::className(),
'actions' => [
//'index' => ['get'],
'login' => ['post', 'put'],
'view' => ['get'],
//'create' => ['get', 'post'],
'update' => ['put'],
//'delete' => ['post', 'delete'],
'delete' => [''],
'test', ['post']
],
];
return $behaviors;
}
in the main.php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/vendor'],
'extraPatterns' => [
'POST,PUT login' => 'login',
'POST logout' => 'logout',
'POST test' => 'test'
],
'tokens' => [
'{id}' => '<id:\\w+>'
]
],
],
]
so when i test and sent GET request to
GET localhost/mywebsite/api/web/v1/vendors/test
it return 404 not 405 status please any help

'extraPatterns' => [
...
'test' => 'test'
]

From Yii2 guideline routing: pretty url, strict parsing always throw \yii\web\NotFound\HttpException.
You can update the controller's beforeAction:
public function beforeAction() {
if (Yii::$app->getRequest()->getMethod() != 'POST') {
throw new \yii\web\MethodNotAllowedHttpException('Only allow POST request');
}
}

Related

Why is the empty POST in YII2 after reinstallation?

We developed our own api for mobile applications, which works on the basis of post requests, but after reinstalling the project on a new server, Yii :: $ app-> request-> post () always returns an empty value. At the same time, Yii :: $ app-> request-> getRawBody () contains a value, but I would not want to rewrite all api.
Tell me what could be the problem and which way to dig? Thanks in advance.
Sending through a mobile application or post through RestClient PHPStorm. Returns emptiness always.
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'only' => ['logout', 'signup'],
'rules' => [
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['login'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::class,
'actions' => [
'login' => ['post', 'get'],
'token' => ['post', 'get'],
'logout' => ['post', 'get'],
],
],
];
}
public function beforeAction($action) {
$this->enableCsrfValidation = false;
return parent::beforeAction($action);
}
public function actionLogin()
{
return Yii::$app->request->post("username");
}
Could be your request is by get() method
$app->request->get();
After a new reinstallation of the project, the problem resolved by itself. Thanks to all.

YII2 error ForbiddenHttpException

When I send post query to actionAnswerTest I get an exception:
[error] 6754#6754: *479979 FastCGI sent in stderr: "PHP message: An
Error occurred while handling another error: exception
'yii\web\ForbiddenHttpException' with message 'You are not allowed to
access this page.'
Rules in controller:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['index', 'partial', 'complete', 'answer', 'answer-test'],
'allow' => true,
'roles' => ['#'],
],
],
'denyCallback' => function($rule, $action) {
return Yii::$app->getResponse()->redirect('denied')->send();
},
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'update' => ['post'],
'test-partial' => ['post'],
'test-complete' => ['post'],
'test-answer' => ['post'],
],
],
[
'class' => ContentNegotiator::className(),
'only' => ['update', 'answer'],
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
];
}
Post query send by authorized user.
Help rename actionAnswerTest to actionAnswertest, and answer-test to answertest

Yii2 REST URL using slugs in place of id in view-slug method

I want to declare a method actionViewSlug($slug) in ScholarshipController in Yii2 REST api, My method is showing Not Found that too not in REST manner i.e. JSON.
Here is my Url Config for ScholarshipController
[
'class' => 'yii\rest\UrlRule',
'controller' => ['scholarship'],
'extraPatterns' => [
'POST filters' => 'filters',
'GET {slug}' => 'view-slug',
],
'tokens' => [
'{slug}' => '<slug>'
],
],
This is behaviors() function in ScholarshipController
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['view', 'index', 'filters', 'view-slug'], // in a controller
// if in a module, use the following IDs for user actions
// 'only' => ['user/view', 'user/index']
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
'cors' => [
'Origin' => ['*'],
'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
'Access-Control-Request-Headers' => ['*'],
'Access-Control-Allow-Credentials' => null,
'Access-Control-Max-Age' => 86400,
'Access-Control-Expose-Headers' => [],
],
],
];
}
Try this URL rule may it should help you.
But befor proceeding with this rule I want to clear you if you are using a module for rest API you must need to define your module ID too in rule either using prefix or direct
[
'class' => 'yii\rest\UrlRule',
'controller' => '<moduleID>/scholarships',
'tokens' => [
'{slug}' => '<slug>',
],
'extraPatterns' => [
'GET,HEAD {slug}' => 'view-slug',
]
],
and where is youe actionViewSlug($slug);
It is good if you share your controller code too. It's simple to use slug with different actions. One more thing here I would like to know why you are defining viewSlug action? Why you are not using the existing view action with slug?
Thanks

How to change access controller redirect/login URL in Yii2?

I have two login systems in my Yii2 application. First is default login system using User table, and second uses sms_account table. In custom controller I've created action for login, actionLogin(). I've added access control for my custom controller, but I'm having problem that when a person is not logged in, it redirects to site/login. I want to change redirect to custom-controller/login URL in Yii2 access control. My code is:
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login'],
'allow' => false,
'roles' => ['#']
],
[
'actions' => ['home'],
'allow' => true,
'roles' => ['#']
]
]
]
];
}
Can anyone tell me how to change access control URL?
You should simply configure your user component :
'user' => [
// ...
'loginUrl' => ['custom-controller/login'],
],
Read more about yii\web\User::$loginUrl.
And it should be :
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?']
],
Read more about Authorization in Yii2.
This is my updated answer . I thinks it's help you
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['index','logout','client-create'], // your own action which permission the login
'rules' => [
[
'actions' => ['index','logout','client-create'], // your own action which permission the login
'allow' => true,
'roles' => ['#'],
],
],
'denyCallback' => function($rule, $action) {
Yii::$app->response->redirect(['login/login']);
},
],
];
}
Try this code.
Note:roles
[
'actions' => ['home'],
'allow' => true,
'roles' => ['?']
'matchCallback' => function ($rule, $action) {
return $this->redirect('index.php?r=controller/action');
}
]

Yii2 controller or configuration raise that only handle the following request methods: GET, HEAD

I am trying to do something very simple a REST response using json format.
I created a simple model:
Model
<?php
namespace app\models;
use Yii;
use yii\db\ActiveRecord;
class Post extends ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'posts';
}
public function rules()
{
return [
[['title', 'content'], 'required'],
];
}
}
And a simple controller:
Controller
namespace app\controllers;
use Yii;
use yii\rest\ActiveController;
class PostsController extends ActiveController
{
public $modelClass = "app\models\Post";
}
?>
It is the configuration of my web.php file:
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [
'request' => [
'cookieValidationKey' => 'wcHYBrv4bXfLJYnWzrpJz_5vARaAeE9U',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'enableStrictParsing' => false,
//'showScriptName' => false,
'rules' => [
'class' => 'yii\rest\UrlRule',
'controller' => 'posts',
]
],
Other attributes...
The most important part (I think so) is the urlManager configuration, maybe I am missing something but I don't know where is the error below.
The error
When I execute a request with method GET, everything is Ok, but with any other method it fail. It is the error:
{
"name": "Method Not Allowed",
"message": "Method Not Allowed. This url can only handle the following request methods: GET, HEAD.",
"code": 0,
"status": 405,
"type": "yii\web\MethodNotAllowedHttpException"
}
I want to get a simple response like this guy got in this video I just did the same configuration, step by step.
Thank you.
UPDATE
There is more information, when I using Postman, I got this Headers result.
I don't understand why only ALLOW -> GET, HEAD
It is the Body result:
Try this configuration:
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'post'],
],
],
See config and full list of available requests in official docs.
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'author',
'pluralize' => false
],
],
],
When I have to do something like that, I have it a little different. Try to change class in urlManager to "yii\rest\UrlRule"
Exemple (this code works for me ) :
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => [
'post']
]
],
]
Now try to acces to this url POST frontend.dev/basic/web/post whit Postman
namespace app\controllers;
use Yii;
use yii\rest\ActiveController;
class PostsController extends ActiveController
{
public $modelClass = "app\models\Post";
//uncomment actions allowed
public function actions()
{
$actions = parent::actions();
// unset($actions['create']);
// unset($actions['update']);
// unset($actions['delete']);
// unset($actions['view']);
// unset($actions['index']);
return $actions;
}
//setup verb allowed
protected function verbs()
{
return [
'create' => ['POST'],
'update' => ['PUT', 'PATCH', 'POST'],
'delete' => ['DELETE'],
'view' => ['GET'],
'index' => ['GET'],
];
}
}
or setup in config file
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['post', 'user', 'etc', 'etc2'],
'pluralize' => false,
'extraPatterns' => [
'POST' => 'create', // 'xx' refers to 'actionXx'
'PUT {id}' => 'update',
'PATCH {id}' => 'update',
'DELETE {id}' => 'delete',
'GET {id}' => 'view',
'GET {count}' => 'index',
],
],
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
],

Categories