It seems that the sfGuard plugin only checks the “remember me” cookie if the user attempts to access a secure module. This is fine if your site requires a login for any access, and thus is always is_secure: on, however if you have any “public” pages which logged in and non-logged in users can access, users that have selected the “remember me” box will not be logged in automatically.
Solution:
Of course this could be fixed in the plugin, but if you do not want to (and shouldn’t) modify the plugin code directly, you can add another filter which will check the cookie. Assuming you have already installed the sfGuardPlugin, and have a “remember me” checkbox implemented, this is all you will need to do to get the automatic logins on non-secure pages:
in apps/yourapp/config/filters.yml add the remember me filter
rendering: ~
web_debug: ~
security:
class: sfGuardBasicSecurityFilter
# generally, you will want to insert your own filters here
remember:
class: rememberMeFilter
cache: ~
common: ~
flash: ~
execution: ~
Now create rememberMeFilter.class.php in apps/yourapp/lib
This example uses Propel
class rememberMeFilter extends sfFilter
{
public function execute ($filterChain)
{
// execute this filter only once, and if the user is not already logged in, and has a cookie set
if ($this->isFirstCall() && !$this->getContext()->getUser()->isAuthenticated()
&& $this->getContext()->getRequest()->getCookie(sfConfig::get('app_sf_guard_plugin_remember_cookie_name', 'sfRemember')))
{
// See if a user exists with this cookie in the remember database
$c = new Criteria();
$c->add(sfGuardRememberKeyPeer::REMEMBER_KEY, $this->getContext()->getRequest()->getCookie(sfConfig::get('app_sf_guard_plugin_remember_cookie_name', 'sfRemember')));
$c->add(sfGuardRememberKeyPeer::IP_ADDRESS, $this->getContext()->getRequest()->getHttpHeader ('addr','remote'));
if ($resultArray = sfGuardRememberKeyPeer::doSelectJoinsfGuardUser($c))
{
$resultRow = current($resultArray);
$this->getContext()->getUser()->signIn($resultRow->getSfGuardUser());
}
}
// execute next filter
$filterChain->execute();
}
}
That should do it, now your users will be logged in on any page if they have the cookie set. The sfGuardPlugin will still take care of setting the cookie and clearing it on logout.
Remember when using these cookies, it’s good practice to ask the user to re-enter their password when doing anything sensitive, like submitting an order or changing any personal details like their password.
A follow up by Shiny explains that you can also get this working by securing modules with empty permission sets like this:
all:
is_secure: on
index:
credentials: []
Be careful with setting that globally though if you’re trying to set a “secure it first, grant permissions later” style system, because with the above – everything is accessible until secured.