Ben siteleri korumak için Zend_Controller_Plugin ve AuthController bir arada kullanın. Bu nedenle ılımlı karmaşıklık, şifre sıfırlar, zorunlu şifre değişiklikleri ve otomatik hesap kilitleme destekler.
Ben Doktrini kullanmak, yani bu tabii ki sadece kesmek ve uygulama içine yapıştırılan olamaz, ancak minimal değişiklikler ile çalışması gerektiğini unutmayın. Benim uygulamaya özgü birkaç yöntem kaldırıldı, ancak tüm genel doğrulama foo var.
Plugin
<?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->hasIdentity()) {
if ('logout' != $request->getActionName()) {
if (! $request->getParam('force_password_change')
&& $this->_checkPasswordExpiry($auth->getIdentity()->username)
) {
$request->setParam('force_password_change', true);
$request->setModuleName('default')
->setControllerName('auth')
->setActionName('change-password');
}
}
} else {
// Defer more complex authentication logic to AuthController
if ('auth' != $this->getRequest()->getControllerName()) {
$redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$redirector->gotoSimple('restricted', 'auth');
}
}
}
protected function _checkPasswordExpiry($username)
{
// Look up user and return true if password is expired
}
}
AuthController
<?php
class AuthController extends Zend_Controller_Action
{
public function init()
{
$this->_auth = Zend_Auth::getInstance();
$this->_errorMessenger = new Zend_Controller_Action_Helper_FlashMessenger();
$this->_errorMessenger->setActionController($this)->init();
$this->_errorMessenger->setNamespace('error');
$this->_noticeMessenger = new Zend_Controller_Action_Helper_FlashMessenger();
$this->_noticeMessenger->setActionController($this)->init();
$this->_noticeMessenger->setNamespace('notice');
$this->view->errors = $this->_errorMessenger->getMessages();
$this->view->notices = $this->_noticeMessenger->getMessages();
}
public function preDispatch()
{
if (! $this->_auth->hasIdentity()) {
if (! in_array($this->_request->getActionName(), array(
'logout', 'identify', 'forgot-password', 'reset-password', 'restricted'))
) {
$this->_redirect('/auth/restricted');
}
}
}
public function restrictedAction()
{
// Shows access restricted page
}
public function logoutAction()
{
$this->_auth->clearIdentity();
Zend_Session::destroy();
$this->_redirect('/');
}
public function identifyAction()
{
if ($this->_request->isPost()) {
$username = $this->_getParam('username');
$password = $this->_getParam('password');
if (empty($username) || empty($password)) {
$this->_flashError('Username or password cannot be blank.');
} else {
$user = new dUser();
$result = $user->login($username, $password);
if ($result->isValid()) {
$user->fromArray((array) $this->_auth->getIdentity());
if ($this->_getParam('changepass') || $user->is_password_expired) {
$this->_redirect('auth/change-password');
return;
}
$this->_doRedirect($user);
return;
} else {
$this->_doFailure($result->getIdentity());
}
}
}
$this->_redirect('/');
}
public function changePasswordAction()
{
if ($this->_request->isPost()) {
$username = $this->_auth->getIdentity()->username;
$formData = $this->_request->getParams();
if (empty($formData['password'])
|| empty($formData['new_password'])
|| empty($formData['confirm_password'])
) {
$this->_flashError('Password cannot be blank.');
$this->_redirect('auth/change-password');
} elseif ($formData['new_password'] !== $formData['confirm_password']) {
$this->_flashError('Password and confirmation do not match.');
$this->_redirect('auth/change-password');
} else {
$user = new dUser();
$result = $user->login($username, $formData['password']);
if ($result->isValid()) {
$user->updatePassword($username, $formData['new_password']);
$this->_flashNotice('Password updated successfully!');
$this->_redirect('/');
} else {
$this->_flashError('Invalid username or password!');
$this->_redirect('auth/change-password');
}
}
}
if ($this->_getParam('force_password_change')) {
$this->view->notice = 'Your password has expired. You must change your password to continue.';
}
}
public function forgotPasswordAction()
{
if ($this->_request->isPost()) {
// Pseudo-random uppercase 6 digit hex value
$resetCode = strtoupper(substr(sha1(uniqid(rand(),true)),0,6));
Doctrine_Query::create()
->update('dUser u')
->set('u.reset_code', '?', array($resetCode))
->where('u.username = ?', array($this->_getParam('username')))
->execute();
$this->_doMail($this->_getParam('username'), $resetCode);
$this->_flashNotice("Password reset request received.");
$this->_flashNotice("An email with further instructions, including your <em>Reset Code</em>, has been sent to {$this->_getParam('username')}.");
$this->_redirect("auth/reset-password/username/{$this->_getParam('username')}");
}
}
public function resetPasswordAction()
{
$this->view->username = $this->_getParam('username');
$this->view->reset_code = $this->_getParam('reset_code');
if ($this->_request->isPost()) {
$formData = $this->_request->getParams();
if (empty($formData['username']) || empty($formData['reset_code'])) {
$this->_flashError('Username or reset code cannot be blank.');
$this->_redirect('auth/reset-password');
} elseif ($formData['new_password'] !== $formData['confirm_password']) {
$this->_flashError('Password and confirmation do not match.');
$this->_redirect('auth/reset-password');
} else {
$user = new dUser();
$result = $user->loginWithResetCode($formData['username'], $formData['reset_code']);
if ($result->isValid()) {
$user->updatePassword($result->getIdentity(), $formData['new_password']);
$user->fromArray((array) $this->_auth->getIdentity());
$this->_flashNotice('Password updated successfully!');
$this->_doRedirect($user);
} else {
$this->_doFailure($result->getIdentity());
$this->_redirect('auth/reset-password');
}
}
}
}
protected function _doRedirect($user)
{
$this->_helper->Redirector->gotoUserDefault($user);
}
protected function _flashError($message)
{
$this->_errorMessenger->addMessage($message);
}
protected function _flashNotice($message)
{
$this->_noticeMessenger->addMessage($message);
}
protected function _doFailure($username)
{
$user = Doctrine_Query::create()
->from('dUser u')
->select('u.is_locked')
->where('u.username = ?', array($username))
->fetchOne();
if ($user->is_locked) {
$this->_flashError('This account has been locked.');
} else {
$this->_flashError('Invalid username or password');
}
}
}