From cb62a8b25b67f4c23148efe5d9e93278651d1901 Mon Sep 17 00:00:00 2001 From: xue <> Date: Wed, 26 Sep 2007 13:15:56 +0000 Subject: added support to remember login. --- framework/Security/IUserManager.php | 13 ++++++ framework/Security/TAuthManager.php | 79 +++++++++++++++++++++++++++++++---- framework/Security/TDbUserManager.php | 66 +++++++++++++++++++++++++++++ framework/Security/TUserManager.php | 37 ++++++++++++++++ 4 files changed, 188 insertions(+), 7 deletions(-) (limited to 'framework/Security') diff --git a/framework/Security/IUserManager.php b/framework/Security/IUserManager.php index 649c41b6..d90450a9 100644 --- a/framework/Security/IUserManager.php +++ b/framework/Security/IUserManager.php @@ -34,6 +34,19 @@ interface IUserManager * @return TUser the user instance, null if the specified username is not in the user database. */ public function getUser($username=null); + /** + * Returns a user instance according to auth data stored in a cookie. + * @param THttpCookie the cookie storing user authentication information + * @return TUser the user instance generated based on the cookie auth data, null if the cookie does not have valid auth data. + * @since 3.1.1 + */ + public function getUserFromCookie($cookie); + /** + * Saves user auth data into a cookie. + * @param THttpCookie the cookie to receive the user auth data. + * @since 3.1.1 + */ + public function saveUserToCookie($cookie); /** * Validates if the username and password are correct. * @param string user name diff --git a/framework/Security/TAuthManager.php b/framework/Security/TAuthManager.php index fcbb64d2..7a6b96a1 100644 --- a/framework/Security/TAuthManager.php +++ b/framework/Security/TAuthManager.php @@ -60,6 +60,14 @@ class TAuthManager extends TModule * @var string the session var name for storing return URL */ private $_returnUrlVarName; + /** + * @var boolean whether to allow auto login (using cookie) + */ + private $_allowAutoLogin=false; + /** + * @var string variable name used to store user session or cookie + */ + private $_userKey; /** * Initializes this module. @@ -215,6 +223,24 @@ class TAuthManager extends TModule $this->getSession()->add($this->getReturnUrlVarName(),$value); } + /** + * @return boolean whether to allow remembering login so that the user logs on automatically next time. Defaults to false. + * @since 3.1.1 + */ + public function getAllowAutoLogin() + { + return $this->_allowAutoLogin; + } + + /** + * @param boolean whether to allow remembering login so that the user logs on automatically next time. Users have to enable cookie to make use of this feature. + * @since 3.1.1 + */ + public function setAllowAutoLogin($value) + { + $this->_allowAutoLogin=TPropertyValue::ensureBoolean($value); + } + /** * Performs the real authentication work. * An OnAuthenticate event will be raised if there is any handler attached to it. @@ -227,11 +253,27 @@ class TAuthManager extends TModule { $application=$this->getApplication(); + // restoring user info from session if(($session=$application->getSession())===null) throw new TConfigurationException('authmanager_session_required'); $session->open(); - $sessionInfo=$session->itemAt($this->generateUserSessionKey()); + $sessionInfo=$session->itemAt($this->getUserKey()); $user=$this->_userManager->getUser(null)->loadFromString($sessionInfo); + + // try authenticating through cookie if possible + if($this->getAllowAutoLogin() && $user->getIsGuest()) + { + $cookie=$this->getRequest()->getCookies()->itemAt($this->getUserKey()); + if($cookie instanceof THttpCookie) + { + if(($user2=$this->_userManager->getUserFromCookie($cookie))!==null) + { + $user=$user2; + $this->updateSessionUser($user); + } + } + } + $application->setUser($user); // event handler gets a chance to do further auth work @@ -258,10 +300,22 @@ class TAuthManager extends TModule } } + /** + * @return string a unique variable name for storing user session/cookie data + * @since 3.1.1 + */ + public function getUserKey() + { + if($this->_userKey===null) + $this->_userKey=$this->generateUserKey(); + return $this->_userKey; + } + /** * @return string a key used to store user information in session + * @since 3.1.1 */ - protected function generateUserSessionKey() + protected function generateUserKey() { return md5($this->getApplication()->getUniqueID().'prado:user'); } @@ -278,7 +332,7 @@ class TAuthManager extends TModule if(($session=$this->getSession())===null) throw new TConfigurationException('authmanager_session_required'); else - $session->add($this->generateUserSessionKey(),$user->saveToString()); + $session->add($this->getUserKey(),$user->saveToString()); } } @@ -288,15 +342,24 @@ class TAuthManager extends TModule * If yes, a user object will be created for the application. * @param string username * @param string password + * @param integer number of seconds that automatic login will remain effective. If 0, it means user logs out when session ends. This parameter is added since 3.1.1. * @return boolean if login is successful */ - public function login($username,$password) + public function login($username,$password,$expire=0) { if($this->_userManager->validateUser($username,$password)) { $user=$this->_userManager->getUser($username); $this->updateSessionUser($user); $this->getApplication()->setUser($user); + + if($expire>0) + { + $cookie=new THttpCookie($this->getUserKey(),''); + $cookie->setExpire(time()+$expire); + $this->_userManager->saveUserToCookie($cookie); + $this->getResponse()->getCookies()->add($cookie); + } return true; } else @@ -312,10 +375,12 @@ class TAuthManager extends TModule { if(($session=$this->getSession())===null) throw new TConfigurationException('authmanager_session_required'); - else + $this->getApplication()->getUser()->setIsGuest(true); + $session->destroy(); + if($this->getAllowAutoLogin()) { - $this->getApplication()->getUser()->setIsGuest(true); - $session->destroy(); + $cookie=new THttpCookie($this->getUserKey(),''); + $this->getResponse()->getCookies()->add($cookie); } } } diff --git a/framework/Security/TDbUserManager.php b/framework/Security/TDbUserManager.php index a2f30642..35cf4fd7 100644 --- a/framework/Security/TDbUserManager.php +++ b/framework/Security/TDbUserManager.php @@ -155,7 +155,10 @@ class TDbUserManager extends TModule implements IUserManager public function getDbConnection() { if($this->_conn===null) + { $this->_conn=$this->createDbConnection($this->_connID); + $this->_conn->setActive(true); + } return $this->_conn; } @@ -178,6 +181,29 @@ class TDbUserManager extends TModule implements IUserManager else throw new TConfigurationException('dbusermanager_connectionid_required'); } + + /** + * Returns a user instance according to auth data stored in a cookie. + * @param THttpCookie the cookie storing user authentication information + * @return TDbUser the user instance generated based on the cookie auth data, null if the cookie does not have valid auth data. + * @since 3.1.1 + */ + public function getUserFromCookie($cookie) + { + return $this->_userFactory->createUserFromCookie($cookie); + } + + /** + * Saves user auth data into a cookie. + * @param THttpCookie the cookie to receive the user auth data. + * @since 3.1.1 + */ + public function saveUserToCookie($cookie) + { + $user=$this->getApplication()->getUser(); + if($user instanceof TDbUser) + $user->saveUserToCookie($cookie); + } } @@ -250,6 +276,46 @@ abstract class TDbUser extends TUser * @return TDbUser the newly created and initialized user instance */ abstract public function createUser($username); + + /** + * Creates a new user instance given the cookie containing auth data. + * + * This method is invoked when {@link TAuthManager::setAllowAutoLogin AllowAutoLogin} is set true. + * The default implementation simply returns null, meaning no user instance can be created + * from the given cookie. + * + * If you want to support automatic login (remember login), you should override this method. + * Typically, you obtain the username and a unique token from the cookie's value. + * You then verify the token is valid and use the username to create a user instance. + * + * @param THttpCookie the cookie storing user authentication information + * @return TDbUser the user instance generated based on the cookie auth data, null if the cookie does not have valid auth data. + * @see saveUserToCookie + * @since 3.1.1 + */ + public function createUserFromCookie($cookie) + { + return null; + } + + /** + * Saves necessary auth data into a cookie. + * This method is invoked when {@link TAuthManager::rememberLogin} is invoked. + * The default implementation does nothing, meaning auth data is not stored in the cookie + * (and thus automatic login is not supported.) + * + * If you want to support automatic login (remember login), you should override this method. + * Typically, you generate a unique token according to the current login information + * and save it together with the username in the cookie's value. + * You should avoid revealing the password in the generated token. + * + * @param THttpCookie the cookie to store the user auth information + * @see createUserFromCookie + * @since 3.1.1 + */ + public function saveUserToCookie($cookie) + { + } } ?> \ No newline at end of file diff --git a/framework/Security/TUserManager.php b/framework/Security/TUserManager.php index 28651de8..f6aee767 100644 --- a/framework/Security/TUserManager.php +++ b/framework/Security/TUserManager.php @@ -250,6 +250,43 @@ class TUserManager extends TModule implements IUserManager } } + /** + * Returns a user instance according to auth data stored in a cookie. + * @param THttpCookie the cookie storing user authentication information + * @return TUser the user instance generated based on the cookie auth data, null if the cookie does not have valid auth data. + * @since 3.1.1 + */ + public function getUserFromCookie($cookie) + { + if(($data=$cookie->getValue())!=='') + { + $data=unserialize($data); + if(is_array($data) && count($data)===2) + { + list($username,$token)=$data; + if(isset($this->_users[$username]) && $token===md5($username.$this->_users[$username])) + return $this->getUser($username); + } + } + return null; + } + + /** + * Saves user auth data into a cookie. + * @param THttpCookie the cookie to receive the user auth data. + * @since 3.1.1 + */ + public function saveUserToCookie($cookie) + { + $user=$this->getApplication()->getUser(); + $username=strtolower($user->getName()); + if(isset($this->_users[$username])) + { + $data=array($username,md5($username.$this->_users[$username])); + $cookie->setValue(serialize($data)); + } + } + /** * Sets a user as a guest. * User name is changed as guest name, and roles are emptied. -- cgit v1.2.3