YII2 error ForbiddenHttpException - php

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

Related

yii2 redirect any page to login page after session timeout

i wanna ask about redirect any page to login page after session timeout in yii2, i try to do this
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => false,
'returnUrl' => 'index.php?r=site/login',
'identityCookie' => [
'name' => '_backendIdentity',
],
],
'session' => [
'name' => 'BACKENDSESSID',
'savePath' => __DIR__ . '/../runtime',
],
but it return to login page when i'm at index.php page, if i go to another action and the session timeout it will return
PHP Notice – yii\base\ErrorException
Trying to get property of non-object
1. in /var/www/html/spmoa/backend/controllers/StaffController.php at line 174
165166167168169170171172173174175176177178179180181182183
public function actionMyProfile() {
error here -> $id = Yii::$app->user->identity->staff->id;
$model = $this->findModel($id);
Please help me
Try with behaviors
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['youraction'],
'allow' => true,
'roles' => ['#'], // you can use matchCallback to create more powerful check
],
],
],
];`enter code here`
}
Please use session and timeout as below in your config/main.php file:
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'authTimeout' => 3600*4, // auth expire 4 hours
],
'session' => [
'class' => 'yii\web\Session',
'cookieParams' => ['httponly' => true, 'lifetime' => 3600*4],
'timeout' => 3600*4, //session expire 4 hours
'useCookies' => true,
],
],
//and in this beforeRequest give actions that can be accessed by guest user.
'as beforeRequest' => [
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'allow' => true,
'actions' => ['login', 'error', 'forgotpassword', 'resetpassword'],
],
[
'allow' => true,
'roles' => ['#'],
],
],
],
You can check condition Before action : If user is logged in or not :
public function beforeAction($action){
if (Yii::$app->user->isGuest){
return $this->redirect(['site/login'])->send(); // login path
}
}

Prevent users from accessing a url directly Yii 2

I have this piece of code that if the user clicks on it the link will be replaced by text making it unable to be clicked again. The problem now is that if the user access it directly in the url so it will simulate a link click. So how do I prevent users from accessing urls directly?
<?php
$isAdded = ActiveSubject::find()->where(['clientid' => $_user,'subjectid' => $subjects['subjectid'],])->exists();
if($isAdded):
?>
<b><p class="text-muted">ADDED</p></b>
<?php else: ?>
<p>
<?= Html::a('<b>ADD</b>',['site/addsubject', 'subjectid'=>$subjects['subjectid'], 'clientid' => $_user],['class' => 'btn-info btn-transparent btn-large']) ?>
</p>
<?php endif; ?>
</td>
<td>
<?= $subjects['slots'] ?>
</td>
<td>
<?php if($isAdded): ?>
<p class="text-primary">Awaiting Confirmation</p>
<?php endif; ?>
In controller
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['addsubject'],
'allow' => true,
'roles' => ['addsubject', 'yourmodelname'],
],
[
'allow' => true,
'roles' => ['superAdmin', 'admin', 'managerModule1', 'managerApp'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'addsubject' => ['post'],
],
],
];
}
checkout this 2 answers also
how to deny the access of url in yii even if we know the url?
how to limit access url view on yii2 by id
In which you can understand the use of filters.
Make it a POST link so that it has to clicked and can't be directly run from the browser
ie.
adding 'data-method' => 'post' to HTML::a
<?= Html::a('<b>ADD</b>',['site/addsubject', 'subjectid'=>$subjects['subjectid'], 'clientid' => $_user],['class' => 'btn-info btn-transparent btn-large', 'data-method' => 'post']) ?>
And in the Access Rules you can add rule to only accept POST Request
i.e
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'addsubject' => ['post'],
],
],
Hope this helps. Thanks.
Edit:
Below is sample for SiteController
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => True,
'actions' => [],
'roles' => []
],
[
'actions' => ['login', 'error', 'captcha'],
'allow' => true,
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
'addsubject' => ['post'],
],
],
];
}

Verbs for custom action is not working in yii2 REST API

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');
}
}

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');
}
]

How to set flash message in Yii2 after denied access to controller

How to set flash message in Yii2 after denied access to controller?
Here is how deny access http://www.yiiframework.com/doc-2.0/yii-filters-accesscontrol.html :
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['create', 'update'],
'rules' => [
// deny all POST requests
[
'allow' => false,
'verbs' => ['POST']
],
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied
],
],
];
}
after this it redirects to site/login. how can I make flash message there like "This section is only for registered users"?
Could you try adding a callback for denial? I hope this works:
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['create', 'update'],
'rules' => [
// deny all POST requests
[
'allow' => false,
'verbs' => ['POST']
],
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied
],
'denyCallback' => function ($rule, $action) {
Yii::$app->session->setFlash('error', 'This section is only for registered users.');
Yii::$app->user->loginRequired();
},
],
];
}
Also you can add denyCallback to each rule:
[
'allow' => false,
'roles' => ['#'],
'denyCallback' => function($rule, $action) {
// callback logic
}
]

Categories