Brett Brett - 1 year ago 187
PHP Question

Having trouble setting cookie via AJAX login with Yii2

I'm using

and I have setup a login process which works fine (cookies as well) via the standard login page which is not

I have built a dropdown login field which works fine at logging them in, however it doesn't seem to set the cookie as the user doesn't stay logged in and there is no bookie created.

I figured that this was because of AJAX and the cookie wasn't being created on the users system, but upon further reading it seems it should work.

I have verified that the cookie value is being set correctly, the only issue is the cookie doesn't seem to being created.

My login code:


function doLogin() {

// Set file to prepare our data
var loadUrl = "../../user/login/";

// Set parameters
var dataObject = $('#login_form').serialize();

// Set status element holder
var status_el = $('#login_status');

// Make sure status element is hidden

// Run request

getAjaxData(loadUrl, dataObject, 'POST', 'json')

.done(function(response) {

if (response.result == 'success') {


} else {




.fail(function() {

// End


function getAjaxData(loadUrl, dataObject, action, type) {

if ($('meta[name="csrf-token"]').length) {
// Add our CSRF token to our data object
dataObject._csrf = $('meta[name="csrf-token"]').attr('content');

return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type



public function actionLogin() {

// Check if they already logged in

if (!Yii::$app->user->isGuest and !Yii::$app->request->isAjax) {
return $this->redirect('/');

if (Yii::$app->request->isAjax) {
// Set our data holder
$response = ['output' => '', 'result' => 'error'];

// Let's send the POST data to the model and see if their login was valid

if (Yii::$app->request->isAjax and $this->user->validate() and $this->user->login()) {

$response['result'] = 'success';

} elseif (!Yii::$app->request->isAjax and Yii::$app->request->isPost and $this->user->validate() and $this->user->login()) {


} else {



if (Yii::$app->request->isAjax) {
echo Json::encode($response);



public function login() {

// Set cookie expire time
$cookie_expire = 3600 * 24 * Yii::$app->params['settings']['cookie_expire'];

return Yii::$app->user->login($this->getUser(), ($this->remember_me ? $cookie_expire : 0));


Answer Source

As I suspected (see my earlier comment) response might not be correctly generated in case of simply echoing the data. Or maybe Content-Type header matters. If someone can confirm this it will be great.

Anyway, I'm glad it works now (data needs to be returned).

And you can use Response handy format as well.

public function actionLogin() {

    // ...

    if (Yii::$app->request->isAjax) {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        return $response;