Jump to content
Craig

ProcessLoginPersistent

Recommended Posts

Hello!
 
About the same time Hari KT asked about "Remember Me" functionality, I identified this as a feature I wanted to implement in some sites under development. Having done this twice before (in CodeIgniter) and based on previous research, I decided to build a ProcessWire module to provide this feature.
 
So far, I have developed and tested this on ProcessWire 2.3. I would welcome any feedback, comments, suggestions and problems from people who are keen to use this. To re-iterate the readme, this module allows users to remain logged in across browser sessions.

  • The module can operate in two ways:
    • Automatically. No code changes, but users do not have a choice.
    • Manually. The module must be called from a site's custom code.
  • Options can be changed in the module configuration page.
  • Enable fingerprinting (IP address and User Agent) as an additional security check.
  • Limit the persistent login functionality by role.
  • Set the name and age of the cookie.
  • Sets an identifier in the session when a user is logged in via a persistent login cookie. This should be used to control access to sensitive information and actions within a site's custom code.
  • Clears login tokens when a potential theft has been identified.

Updated: LoginPersist on GitHub

  • Like 15

Share this post


Link to post
Share on other sites

Thanks sounds nice! :)

Just had a quick look at the code: I think that it does not need to be a Process module. Process modules are only needed if you have a module that runs in the Pw backend. In your case, you could just extend WireData instead of Process. Anyway, thanks again for writing this!

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

Thanks Wanze! I really wasn't sure what the best naming format for this was, so I'm definitely open to changing it to something more suitable :)

Edit: I have just discovered this post - How to present your module - which confirms that Process definitely isn't needed here. It has now been renamed to LoginPersist. If anyone has already installed it, please uninstall, remove, and install again :)

  • Like 1

Share this post


Link to post
Share on other sites

@Craig, thanks for this - just the job for a project I'm on at the moment. Installed on PW 2.4.4 and seems to be working fine.

Share this post


Link to post
Share on other sites

You're welcome. Thanks for the feedback DaveP! :)

Share this post


Link to post
Share on other sites

Thanks Dave.

That's not something that I've looked at specifically - I copied the parameter values from elsewhere in ProcessWire - and the domain one is just set to null.

setcookie($this->get('cookieName'), $value, $expires, '/', null, false, true);

I haven't been caught out by this issue as I've always set up individual hosts for each site I work on; but definitely something to be aware of.

It would be relatively easy to add a configuration field to the module for a user-specified cookie domain though, if it was required :)

  • Like 1

Share this post


Link to post
Share on other sites

I quite often use Chrome & Chrome Canary so that I can be logged in to the same site (PW sites or others) as two different users, and to avoid even trying to be logged into 2 Google accounts in the same Chrome instance. The only problem is that, by its very nature, Canary can be 'unpredictable', shall we say.

Best thing is to use Chrome & Firefox and avoid all the problems. ;)

FWIW, Craig, I shouldn't go out of your way just to accommodate oddballs like me. :P

Share this post


Link to post
Share on other sites

@Dave, I use Incognito Window for that. I love it because I don't have to start 2 browsers and the Incognito window looks different then the default.

Chrome on the mac: [ shift ] + [ command ] + [ n ]

  • Like 1

Share this post


Link to post
Share on other sites

I use Chrome as my main browser; and when I need to do account or session based testing I usually head to Incognito mode as well :)

  • Like 1

Share this post


Link to post
Share on other sites

This is a great module, appears to work great and is exactly what I needed.

I just tripped over something, not necessarily an issue with this specific module, but I'm getting this

Notice: Undefined index: HTTP_USER_AGENT in <CUT>/modules/LoginPersist/LoginPersist.module on line 508

When I bootstrap Processwire for use in a backend cron job.  It seems like in init() there should be some check to see if Processwire is running in the context of a web site.

Not sure the best way to fix it, and I admit most users probably don't bootstrap PW for use in a cron.  It's an edge case for sure.  Here's what I did:

   public function init() {
        if (php_sapi_name() != 'cli') {
            $this->set('doLoginHook', true);
            $this->session->addHookAfter('login', $this, 'loggedIn');
            $this->session->addHookAfter('logout', $this, 'loggedOut');
            $this->_pruneLogins();
            $this->attemptLogin();
        }
    }

Detecting if PHP is being used via CLI with php_sapi_name() is based off an answer on stackoverflow at http://stackoverflow.com/questions/343557/how-to-distinguish-command-line-and-web-server-invocation

Great work on this module!

  • Like 2

Share this post


Link to post
Share on other sites

@bracketfire: that's a cool way to do it, but whether it's the best approach depends on what you're trying to achieve. It's entirely possible, although quite rare, for $_SERVER['HTTP_USER_AGENT'] to be missing from non-cli requests too (it's a header after all), so checking for cli use doesn't entirely prevent this notice from appearing.

If the underlying issue is that $_SERVER['HTTP_USER_AGENT'] isn't found and it's necessary for this module to work at all (haven't checked the code so can't really tell), it would probably make more sense to simply check for that specifically with isset().

On the other hand, if the module isn't useful in cli use at all and $_SERVER['HTTP_USER_AGENT'] isn't necessary for it to work properly in non-cli use case, it would make most sense to apply your fix (skip the module entirely for cli users) and add an isset() check to prevent unnecessary notices for non-cli clients that don't, for any given reason, send this header :)

(Sorry, meant to point out something simple, but this turned into a kind of a long rant anyway..)

  • Like 2

Share this post


Link to post
Share on other sites

Hi bracketfire, thanks for your comments! I'm pleased you're finding the module useful.

The HTTP_USER_AGENT is used in conjunction with the IP address for "fingerprinting" - adding additional security checks against the client. It utilises the same methods as the main ProcessWire session class.

In the first instance, I should probably update the fingerprinting code to use the user agent value only if its present; and additionally, look into changing the init() function to not do anything on the command line.

I'm not sure that there will be one true way to detect with absolute certainty CLI vs HTTP, as this SO thread discusses, but php_sapi_name() looks the closest. It's probably no use running this module when in CLI mode anyway, so this is something I will look at.

Thanks again!

Craig.

Share this post


Link to post
Share on other sites

I'm not sure that there will be one true way to detect with absolute certainty CLI vs HTTP, as this SO thread discusses, but php_sapi_name() looks the closest. It's probably no use running this module when in CLI mode anyway, so this is something I will look at.

Just for the record, here's how PW itself (in current dev branch) is doing it:

$config->cli = (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || ($_SERVER['argc'] > 0 && is_numeric($_SERVER['argc']))));
  • Like 4

Share this post


Link to post
Share on other sites

Thank you for this module!

I'm trying to implement it on a 2.5.2 install and have some issues/questions.

I installed, activated and configured the module to be automatic without fingerprint and only assigned to 1 specific role.

 

These might me dumb questions, but I'm still asking  :undecided:

1) is this module intended for backend or frontend usage or both?

2) how do I go about testing?

I logged in to the backend on a live server in Chrome with a user that has the specified role. After login I can see that a persist cookie has been created.

Then I opened a Chrome incognito window and went to the backend login address. But I'm still presented with the login form.

I want to use it on the frontend. So I switched off automatic mode and added this to my login logic:

	//login user
	$u = $session->login($username, $pass);

	if($u) {
		// make login persistent if user checked Remember me
		if ($u->login_persist && $u->login_persist == "1") {
			$persist = wire('modules')->get('LoginPersist');
			$persist->persist();
		}
        }
 

When I now login to the frontend, I can also see that a persist cookie is created.

I tried testing it the same way as above with the backend login. No success.

When I log out of the frontend session, the cookie is gone.

4) Will the login still persist, even if the user logged out of there previous session? I guess not.

Share this post


Link to post
Share on other sites

Hi gebeer

It is designed to work for either back, or front, or both. It's up to you.

The main flaw in your testing is using incognito mode. That is a totally separate browser session, with different cookies. So there is no way that logging in with persist, in one browser window will work as you expect it to with incognito.

The better way to test it is to delete the ProcessWire session cookie. This will log you out. But then LoginPersist will see the persist cookie is present, and log you back in.

The module is designed to remove the persistent cookie when the user actively chooses to log out. The idea behind it is to allow the user to have a persistent login state until they choose to log out. To remain logged in with this, simply do not log out.

  • Like 2

Share this post


Link to post
Share on other sites

Thank you for clarifying.

So I guess your module is restoring the session then.

Or do I have to pick up and process the cookie data in my custom login logic?

Cheers

Share this post


Link to post
Share on other sites

The module will handle all of that for you :)

Share this post


Link to post
Share on other sites

Thank you again for the explanation. I followed your advice for testing and can see now that it is working.

Share this post


Link to post
Share on other sites

For some reason, this module doesn't work for me on my site. PW 2.7.2 and only the Superuser given a persistent login. Both sessionExpireSeconds and session.cookie.lifetime are set to 86400, still login lasts less than an hour. This works fine on a local MAMP server.

Share this post


Link to post
Share on other sites
4 hours ago, franctic-aerobic said:

@Craig A Rodway: Is this module compatible with ProcessWire 3.0+?

It works without problems with the latest stable version 😉 

  • Like 1

Share this post


Link to post
Share on other sites

Hi!

Great Module.

I just want to have a "remember me" checkbox in the login form.
So the user can decide ...
Ho can i add this?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Tyssen
      I have a client who is reporting that in the last couple of days they can no longer login to their site with their normal browser (Chrome). Using another browser or an incognito window works.
      I've tried logging into the site using the same login details in my usual browser (Firefox) and have had no problems.
      The site is a membership site and today other members are reporting the same problem.
      The site is running 3.0.148 and has the session handler DB and login throttle modules installed. It was recently upgraded to 3.x from 2.x. But no changes have been made to the site between the time when they were able to login OK and when the problem started happening.
    • By codevark
      The Minimal Site works fine, but if I try to login as admin, I have no idea what the credentials are.
      I did not do the "install" process myself. The OVA came with everything set up, but there's no mention of the PW admin credentials being set to some initial value.
      Wondering if anyone else has tried the Bitnami OVA and if there's a simple answer.
      --Pete
    • By franciccio-ITALIANO
      Hi, I need to provide a quite complex user registration form: description, subdescription, drop-down lists etc. 
      Through this registration, users will be able to access and comment.
      If someone responds to their comments, I would like a NOTIFICATION to appear when accessing their panel.
      My social interaction project is just that, it seems simple, I don't need more.
      Now I am undecided whether to use buddypress, elgg, or a native processwire system.
      What do you recommend? 
      If you recommend processwire, which modules should I install?
      Do they work or is processwire too immature for that?
      Translated with www.DeepL.com/Translator (free version)
    • By abdulqayyum
      Dear processwire community,
      i have a problem in loginRegister module, i could not add custom field in login and register page.
      i read from plugin documentation. they are saying.
      " By default, the email and password fields are required for both forms. You may want to add more fields. To do this, you’ll need to add fields to your “user” template. You can add fields to your user template in the admin by going to “Setup > Templates > Show system templates > user”.

      but i could not find similar scenario like “Setup > Templates > Show system templates > user”
      i can see just "Setup > Templates" not seeing "Show system templates > user" in my admin panel.

      Please help me in this case that how i can add custom field in these two page.
      Regards AbdulQayyum

    • By Anton
      Hi there,
      I'm working with Processwire 3. Before summer I had issues to load to my backend. I finally managed to connect thanks to this : 
      $admin = wire('users')->get('admin');
      $admin->setOutputFormatting(false);
      $admin->set('pass', 'yo12345ZZ')
      $admin->save('pass');
      But later, the problem evolved: when I logged in to the site, the login page redirected me to the home. I didn't find any information about it on the web.
      But recently, the redirection has changed, now it is the login page that reloads when you connect. 
      I don't know where to start to fix this. It looks like sorcery.
      Thank you for all the help you can give me.
       
×
×
  • Create New...