Dependencies
composer require zfcampus/zf-api-problem
<?php | |
namespace Application\Controller; | |
use Application\Form\LoginForm; | |
use Zend\Authentication\AuthenticationService; | |
use Zend\Mvc\Controller\AbstractActionController; | |
use Zend\View\Model\JsonModel; | |
use ZF\ApiProblem\ApiProblem; | |
use ZF\ApiProblem\ApiProblemResponse; | |
class AuthController extends AbstractActionController | |
{ | |
/** | |
* @var AuthenticationService | |
*/ | |
protected $authenticationService; | |
public function __construct(AuthenticationService $authenticationService) | |
{ | |
$this->authenticationService = $authenticationService; | |
} | |
public function indexAction() | |
{ | |
$form = new LoginForm(); | |
$layout = $this->layout(); | |
$layout->setTemplate('layout/login'); | |
return [ | |
'form' => $form, | |
'isLoginError' => $isLoginError, | |
]; | |
} | |
public function ajaxLoginAction() | |
{ | |
$form = new LoginForm(); | |
$request = $this->getRequest(); | |
if ($request->isPost()) { | |
$data = $this->params()->fromPost(); | |
$form->setData($data); | |
if ($form->isValid()) { | |
$data = $form->getData(); | |
$adapter = $this->authenticationService->getAdapter(); | |
$adapter->setIdentity($data['username']); | |
$adapter->setCredential($data['password']); | |
$result = $this->authenticationService->authenticate(); | |
if ($result->isValid()) { | |
$authValid = true; | |
} else { | |
$isLoginError = true; | |
} | |
} else { | |
$isLoginError = true; | |
} | |
} | |
if ($isLoginError) { | |
return new ApiProblemResponse(new ApiProblem(400, 'Error Login', null, null, $form->getMessages())); | |
} | |
return new JsonModel([ | |
'message' => 'Login success', | |
'status' => 'Ok', | |
]); | |
} | |
public function logoutAction() | |
{ | |
$this->authenticationService->clearIdentity(); | |
return $this->redirect()->toRoute('login'); | |
} | |
} |
<?php | |
$form->get('username')->setAttributes([ | |
'id' => 'username', | |
'class'=>'form-control', | |
'placeholder'=>'Email address', | |
'required' => true, | |
'autofocus' => true | |
]) | |
->setLabelAttributes([ | |
'class' => 'col-sm-4 col-form-label text-md-right' | |
]); | |
$form->get('password')->setAttributes([ | |
'id' => 'password', | |
'class'=>'form-control', | |
'placeholder'=>'Password', | |
'required' => true, | |
]) | |
->setLabelAttributes([ | |
'class' => 'col-sm-4 col-form-label text-md-right' | |
]); | |
$form->get('csrf')->setAttributes([ | |
'id' => 'csrf', | |
]); | |
$form->get('submit')->setAttributes([ | |
'class' => 'btn btn-primary loginButton', | |
]); | |
?> | |
<div class="row justify-content-center"> | |
<div class="col-md-8 pt-5"> | |
<div class="card"> | |
<div class="card-header"> | |
Login | |
</div> | |
<div class="card-body"> | |
<form method="post"> | |
<?= $this->formElement($form->get('csrf')) ?> | |
<div class="alert alert-warning d-none" role="alert"> | |
Incorrect login and/or password. | |
</div> | |
<div class="form-group row"> | |
<?= $this->formLabel($form->get('username')) ?> | |
<div class="col-md-6"> | |
<?= $this->formElement($form->get('username')) ?> | |
</div> | |
</div> | |
<div class="form-group row"> | |
<?= $this->formLabel($form->get('password')) ?> | |
<div class="col-md-6"> | |
<?= $this->formElement($form->get('password')) ?> | |
</div> | |
</div> | |
<div class="form-group row"> | |
<div class="col-md-6 offset-md-4"> | |
<?= $this->formElement($form->get('submit')) ?> | |
</div> | |
</div> | |
</form> | |
</div> | |
</div> | |
</div> | |
</div> | |
<?php $this->headScript()->appendFile('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js') ?> | |
<?php $this->inlineScript()->captureStart() ?> | |
jQuery(document).ready(function() { | |
$('.loginButton').on('click', function(event) { | |
event.preventDefault(); | |
var username = $('#username').val(), | |
password = $('#password').val(), | |
csrf = $('#csrf').val(); | |
$.post('<?= $this->url('login', ['action' => 'ajax-login']) ?>', {username: username, password: password, csrf: csrf}, function(data) { | |
if (data.status == 'Ok') { | |
window.location.href = '<?= $this->url('home') ?>'; | |
} | |
}) | |
.fail(function(xhr, textStatus, errorThrown) { | |
console.log(xhr.responseText); | |
$('alert-warning').removeClass('d-none'); | |
}); | |
}); | |
}); | |
<?php $this->inlineScritp()->captureEnd() ?> |
<?php | |
namespace Application\Form; | |
use Zend\Form\Element\Checkbox; | |
use Zend\Form\Element\Password; | |
use Zend\Form\Element\Text; | |
use Zend\Form\Form; | |
use Zend\InputFilter; | |
use Zend\Validator; | |
class LoginForm extends Form | |
{ | |
public function __construct($name = null, array $options = []) | |
{ | |
parent::__construct($name, $options); | |
$this->setAttribute('method', 'POST'); | |
$this->add([ | |
'type' => Text::class, | |
'name' => 'username', | |
'options' => [ | |
'label' => 'Your username', | |
], | |
]); | |
$this->add([ | |
'type' => Password::class, | |
'name' => 'password', | |
'options' => [ | |
'label' => 'Password', | |
], | |
]); | |
$this->add([ | |
'type' => Checkbox::class, | |
'name' => 'remember_me', | |
'options' => [ | |
'label' => 'Remember me' | |
], | |
]); | |
// Add the CSRF field | |
$this->add([ | |
'type' => 'csrf', | |
'name' => 'csrf', | |
'options' => [ | |
'csrf_options' => [ | |
'timeout' => 600 | |
] | |
], | |
]); | |
// Add the Submit button | |
$this->add([ | |
'type' => 'submit', | |
'name' => 'submit', | |
'attributes' => [ | |
'value' => 'Sign in', | |
'id' => 'submit', | |
], | |
]); | |
$this->addInputFilter(); | |
} | |
protected function addInputFilter() | |
{ | |
$factory = new InputFilter\Factory(); | |
$inputfilter = $factory->createInputFilter([ | |
'username' => [ | |
'required' => true, | |
'validators' => [ | |
[ | |
'name' => Validator\StringLength::class, | |
'options' => [ | |
'min' => 3, | |
'max' => 256 | |
], | |
], | |
], | |
], | |
'password' => [ | |
'required' => true, | |
'validators' => [ | |
[ | |
'name' => Validator\StringLength::class, | |
'options' => [ | |
'min' => 3, | |
'max' => 256 | |
], | |
], | |
], | |
], | |
'remember_me' => [ | |
'required' => false, | |
], | |
]); | |
$this->setInputFilter($inputfilter); | |
} | |
} | |