Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bad Request (#400) in Yii2 when trying to login

Tags:

php

yii

yii2

I am getting Bad Request (#400) error while I am trying to login into a system. I am working on localhost.

Main layout:

<html lang="<?= Yii::$app->language ?>">
    <head>
        <meta charset="<?= Yii::$app->charset; ?>">
        <meta name="viewport"
              content="width=device-width, initial-scale=1, maximum-scale=1"/>
        <?= Html::csrfMetaTags(); ?>
        <title><?= Html::encode($this->title); ?></title>
        <?php $this->head(); ?>
    </head>
    <body></body>
</html>

View (login.php):

<?php

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title; ?>

<div class="container w-xxl w-auto-xs">
    <a href class="navbar-brand block m-t">OpenXcell Pvt. Ltd.</a>
    <div class="m-b-lg">
        <div class="wrapper text-center">
            <strong>Sign in to get in touch</strong>
        </div>
        <form action="/advanced/admin/site/login"
              method="post"
              name="form"
              class="form-validation">
            <div class="list-group list-group-sm">
                <div class="list-group-item">
                    <input type="text" placeholder="Email" required
                           class="form-control no-border" name="username">
                </div>
                <div class="list-group-item">
                    <input type="password" placeholder="Password" required
                           class="form-control no-border" name="password">
                </div>
            </div>
            <button type="submit" class="btn btn-lg btn-primary btn-block">
                Log in
            </button>
        </form>
    </div>
</div>

Site Controller:

<?php namespace backend\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use app\models\LoginForm;
use yii\filters\VerbFilter;

class SiteController extends Controller {
    public function behaviors() {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['login', 'error'],
                        'allow' => true
                    ],
                    [
                        'actions' => ['logout', 'index'],
                        'allow' => true,
                        'roles' => ['@']
                    ]
                ]
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => ['logout' => ['post']]
            ]
        ];
    }

    public function actions() {
        return ['error' => ['class' => 'yii\web\ErrorAction']];
    }

    public function actionIndex() {
        return $this->render('index');
    }

    public function actionLogin() {
        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        } else {
            return $this->render('login', ['model' => $model]);
        }
    }

    public function actionLogout() {
        Yii::$app->user->logout();
        return $this->goHome();
    }
}

Model:

<?php namespace app\models;

use Yii;
use yii\base\Model;

class LoginForm extends Model {
    public $username;
    public $password;
    public $rememberMe = true;
    private $_user = false;

    public function rules() {
        return [
            [['username', 'password'], 'required'],
            ['rememberMe', 'boolean'],
            ['password', 'validatePassword']
        ];
    }

    public function validatePassword($attribute, $params) {
        if (!$this->hasErrors()) {
            $user = $this->getUser();
            if (!$user || !$user->validatePassword($this->password)) {
                $this->addError($attribute, 'Incorrect username or password.');
            }
        }
    }

    public function login() {
        $duration = $this->rememberMe ? 3600 * 24 * 30 : 0;
        if ($this->validate()) {
            return Yii::$app->user->login($this->getUser(), $duration);
        } else {
            return false;
        }
    }

    public function getUser() {
        if ($this->_user === false) {
            $this->_user = User::findByUsername($this->username);
        }
        return $this->_user;
    }
}

Why am I getting this error? What is wrong in my code?

like image 615
Pathik Vejani Avatar asked Mar 16 '23 15:03

Pathik Vejani


1 Answers

Add CSRF token. If you don't want to use ActiveForm, then add this token explicitly (in case of ActiveForm is used, the token will be added automatically):

<form action="" method="post">
    <input type ="hidden"
           name ="<?php echo Yii::$app->request->csrfParam; ?>"
           value="<?php echo Yii::$app->request->csrfToken; ?>">
</form>

To disable CSRF validation for the whole controller:

class DemoController extends Controller {
    public $enableCsrfValidation = false;
}

To disable CSRF validation for a certain action:

class DemoController extends Controller {
    public function beforeAction($action) {
        if (in_array($action->id, ['example'])) {
            $this->enableCsrfValidation = false;
        }
        return parent::beforeAction($action);
    }
}

Also, read about security-passwords.

like image 93
Oleksandr Pyrohov Avatar answered Mar 31 '23 16:03

Oleksandr Pyrohov