Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I use a combination of a Zend_Controller_Plugin and an AuthController to protect my sites. It supports password resets, forced password changes, and automatic account locking, hence the moderate complexity. </p> <p>Note that I use Doctrine, so this obviously can't just be cut and pasted into your application, but it should function with minimal changes. I removed a few methods specific to my application, but all the general authentication foo is there.</p> <p><strong>Plugin</strong></p> <pre><code>&lt;?php class Hobo_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract { public function preDispatch(Zend_Controller_Request_Abstract $request) { $auth = Zend_Auth::getInstance(); if ($auth-&gt;hasIdentity()) { if ('logout' != $request-&gt;getActionName()) { if (! $request-&gt;getParam('force_password_change') &amp;&amp; $this-&gt;_checkPasswordExpiry($auth-&gt;getIdentity()-&gt;username) ) { $request-&gt;setParam('force_password_change', true); $request-&gt;setModuleName('default') -&gt;setControllerName('auth') -&gt;setActionName('change-password'); } } } else { // Defer more complex authentication logic to AuthController if ('auth' != $this-&gt;getRequest()-&gt;getControllerName()) { $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector'); $redirector-&gt;gotoSimple('restricted', 'auth'); } } } protected function _checkPasswordExpiry($username) { // Look up user and return true if password is expired } } </code></pre> <p><strong>AuthController</strong></p> <pre><code>&lt;?php class AuthController extends Zend_Controller_Action { public function init() { $this-&gt;_auth = Zend_Auth::getInstance(); $this-&gt;_errorMessenger = new Zend_Controller_Action_Helper_FlashMessenger(); $this-&gt;_errorMessenger-&gt;setActionController($this)-&gt;init(); $this-&gt;_errorMessenger-&gt;setNamespace('error'); $this-&gt;_noticeMessenger = new Zend_Controller_Action_Helper_FlashMessenger(); $this-&gt;_noticeMessenger-&gt;setActionController($this)-&gt;init(); $this-&gt;_noticeMessenger-&gt;setNamespace('notice'); $this-&gt;view-&gt;errors = $this-&gt;_errorMessenger-&gt;getMessages(); $this-&gt;view-&gt;notices = $this-&gt;_noticeMessenger-&gt;getMessages(); } public function preDispatch() { if (! $this-&gt;_auth-&gt;hasIdentity()) { if (! in_array($this-&gt;_request-&gt;getActionName(), array( 'logout', 'identify', 'forgot-password', 'reset-password', 'restricted')) ) { $this-&gt;_redirect('/auth/restricted'); } } } public function restrictedAction() { // Shows access restricted page } public function logoutAction() { $this-&gt;_auth-&gt;clearIdentity(); Zend_Session::destroy(); $this-&gt;_redirect('/'); } public function identifyAction() { if ($this-&gt;_request-&gt;isPost()) { $username = $this-&gt;_getParam('username'); $password = $this-&gt;_getParam('password'); if (empty($username) || empty($password)) { $this-&gt;_flashError('Username or password cannot be blank.'); } else { $user = new dUser(); $result = $user-&gt;login($username, $password); if ($result-&gt;isValid()) { $user-&gt;fromArray((array) $this-&gt;_auth-&gt;getIdentity()); if ($this-&gt;_getParam('changepass') || $user-&gt;is_password_expired) { $this-&gt;_redirect('auth/change-password'); return; } $this-&gt;_doRedirect($user); return; } else { $this-&gt;_doFailure($result-&gt;getIdentity()); } } } $this-&gt;_redirect('/'); } public function changePasswordAction() { if ($this-&gt;_request-&gt;isPost()) { $username = $this-&gt;_auth-&gt;getIdentity()-&gt;username; $formData = $this-&gt;_request-&gt;getParams(); if (empty($formData['password']) || empty($formData['new_password']) || empty($formData['confirm_password']) ) { $this-&gt;_flashError('Password cannot be blank.'); $this-&gt;_redirect('auth/change-password'); } elseif ($formData['new_password'] !== $formData['confirm_password']) { $this-&gt;_flashError('Password and confirmation do not match.'); $this-&gt;_redirect('auth/change-password'); } else { $user = new dUser(); $result = $user-&gt;login($username, $formData['password']); if ($result-&gt;isValid()) { $user-&gt;updatePassword($username, $formData['new_password']); $this-&gt;_flashNotice('Password updated successfully!'); $this-&gt;_redirect('/'); } else { $this-&gt;_flashError('Invalid username or password!'); $this-&gt;_redirect('auth/change-password'); } } } if ($this-&gt;_getParam('force_password_change')) { $this-&gt;view-&gt;notice = 'Your password has expired. You must change your password to continue.'; } } public function forgotPasswordAction() { if ($this-&gt;_request-&gt;isPost()) { // Pseudo-random uppercase 6 digit hex value $resetCode = strtoupper(substr(sha1(uniqid(rand(),true)),0,6)); Doctrine_Query::create() -&gt;update('dUser u') -&gt;set('u.reset_code', '?', array($resetCode)) -&gt;where('u.username = ?', array($this-&gt;_getParam('username'))) -&gt;execute(); $this-&gt;_doMail($this-&gt;_getParam('username'), $resetCode); $this-&gt;_flashNotice("Password reset request received."); $this-&gt;_flashNotice("An email with further instructions, including your &lt;em&gt;Reset Code&lt;/em&gt;, has been sent to {$this-&gt;_getParam('username')}."); $this-&gt;_redirect("auth/reset-password/username/{$this-&gt;_getParam('username')}"); } } public function resetPasswordAction() { $this-&gt;view-&gt;username = $this-&gt;_getParam('username'); $this-&gt;view-&gt;reset_code = $this-&gt;_getParam('reset_code'); if ($this-&gt;_request-&gt;isPost()) { $formData = $this-&gt;_request-&gt;getParams(); if (empty($formData['username']) || empty($formData['reset_code'])) { $this-&gt;_flashError('Username or reset code cannot be blank.'); $this-&gt;_redirect('auth/reset-password'); } elseif ($formData['new_password'] !== $formData['confirm_password']) { $this-&gt;_flashError('Password and confirmation do not match.'); $this-&gt;_redirect('auth/reset-password'); } else { $user = new dUser(); $result = $user-&gt;loginWithResetCode($formData['username'], $formData['reset_code']); if ($result-&gt;isValid()) { $user-&gt;updatePassword($result-&gt;getIdentity(), $formData['new_password']); $user-&gt;fromArray((array) $this-&gt;_auth-&gt;getIdentity()); $this-&gt;_flashNotice('Password updated successfully!'); $this-&gt;_doRedirect($user); } else { $this-&gt;_doFailure($result-&gt;getIdentity()); $this-&gt;_redirect('auth/reset-password'); } } } } protected function _doRedirect($user) { $this-&gt;_helper-&gt;Redirector-&gt;gotoUserDefault($user); } protected function _flashError($message) { $this-&gt;_errorMessenger-&gt;addMessage($message); } protected function _flashNotice($message) { $this-&gt;_noticeMessenger-&gt;addMessage($message); } protected function _doFailure($username) { $user = Doctrine_Query::create() -&gt;from('dUser u') -&gt;select('u.is_locked') -&gt;where('u.username = ?', array($username)) -&gt;fetchOne(); if ($user-&gt;is_locked) { $this-&gt;_flashError('This account has been locked.'); } else { $this-&gt;_flashError('Invalid username or password'); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload