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