Jump to content

Integrating a member / visitor login form


thetuningspoon

Recommended Posts

I'm looking into developing a site with a "members-only" section in the front-end. I've been playing around with creating new users in the back end and then using the API to show certain content only to members logged in with certain roles, etc. It's really fantastic and I love how flexible it is.

Now I'm at the point where I'd like to provide a form which displays to visitors who are not logged in and allows them to do so (obviously I don't want to have to direct users to the default admin login page to log in). However, I have no idea how to do this... I tried looking at the code for the admin login page to see if I could borrow from that, but I can't even figure out where the code for the form is!

Any help would be much appreciated, as always :)

Link to comment
Share on other sites

I agree with nik, that that is useful. But wire('session')->login activates more things and somehow I think it's good to get respond back from PW.

SessionLoginThrottle for example, throttles the time up to 300 seconds,after that you're be able tp login again.

Actually I'm trying to write a module for frontend members.

covering:

  • 'changePassword',
  • 'confirmRegister',
  • 'forgotPassword',
  • 'login',
  • 'logout',
  • 'profile',
  • 'register',
  • 'resetPassword',
  • 'updateProfile'

I'm kinda stuck on the "login" due the lack of OOP knowledge. I don't know how to retrieve the data back from for instance "SessionLoginThrottle.module" or any other classes. Figured out SELF:: for example, but don't know where PARENT:: references to for example....

Realy have no clue, maybee I even start wrong :-)

class FrontMembers extends WireData implements Module, ConfigurableModule {
}

I'll continue fighting this week...

  • Like 2
Link to comment
Share on other sites

Hi Ryan,

Is there any downside to using something like this to create a random/temporary password?

$pass = uniqid(); // generate random pass
$user->pass = $pass; // Update PW with random pass

It seems to work fine for me, I'm just curious if there's a reason not to use this method.

Link to comment
Share on other sites

The disadvantage with uniqid() is that its output is predictable since the value returned is based on the current timestamp. So on the surface, it seems there's possibility for that to be exploited, although it might be challenging.

The password generation I put in the example above is based all around random characters, which aren't predictable other than the set which they come from (a-z2-9) and the length (between 9 and 12). I think this is pretty strong. However, the security of it could be increased by adding more to the set of possible characters (punctuation, upper/lower, etc.) and increasing the possible length range, like up to 30 characters or something. I opted to limit the character set and exclude the letters that are easily confused with each other, like "o O 0" and "i I l 1", just in case people are hand-typing (rather than copy/pasting)… less support burden.

Another thing I might add to the code would be to make it only work with users of a certain role. But that would be pretty site-specific, so left it out here.

  • Like 5
Link to comment
Share on other sites

Thank you Ryan & renobird. I love the big explanations & the time you took to write this all down.

...and among a million other reasons, it's responses like this that make Processwire incredible.

There's a lot in there I can learn from. Thanks for sharing.

:)

Total Right !

continue with the fight now....

  • Like 1
Link to comment
Share on other sites

ryan said: 1. In Admin > Setup > Fields, create a new text field called 'tmp_pass' and add it to the 'user' template.

I wished to do this from within the "public function ___install()" in the module.

But I can't find anything on creating new fields, can someone help me out?

dumb me:

Edited by Martijn Geerts
Link to comment
Share on other sites

  • 3 months later...
<?php if sense_of_humor ?>

Wow, and we have to do everything ourselves?

<?php endif ?>

Great topic, really learned a lot. :)

EDIT:

Everything working except that part where reset email was sent, password did not reset at all. Would be also nice to have another page which really resets the password, ie email will include link to that page. That way, if user ignores the email, no real changes would be made.

Link to comment
Share on other sites

Everything working except that part where reset email was sent, password did not reset at all. Would be also nice to have another page which really resets the password, ie email will include link to that page. That way, if user ignores the email, no real changes would be made.

If you are going off one of my earlier posts in here, this was the reason for the new tmp_pass variable. No changes are made to the password unless the user is logged in and changes the password manually. The tmp_pass is a one-time code that expires as soon as you login (whether using the real pass or the tmp_pass). The tmp_pass code is only visible at the account owner's email. I've found this method works well for simple account authentication situations. Of course, it does assume the user's email is secure, as many "password reset" functions do. For high security situations, you don't want to trust that the user's email is secure.

  • Like 1
Link to comment
Share on other sites

Thanks, that explains a lot. Just perfect for my needs. Checked my log and found out that my error is actually coming from not being able to create user template.(?)

EDIT: the actual error is "TemplateFile : Duplicate entry 'user' for key 'name' INSERT INTO `fieldgroups` SET `name`='user'"

When you say: add it to the 'user' template, is 'user' built-in template or something else?

Link to comment
Share on other sites

  • 2 months later...

I have copied Ryan's custom login code and tested out on my server and it work great! Thank you so much Ryan!

Since I was testing with various users which I just created using Admin panel and provided same email address to different users and I find that I still receive email with temp password but when I supply username with new temp password on the custom login screen I got "Login Failed!" message! I was wondering if its going to work with same email address for different users?

Link to comment
Share on other sites

  • 1 month later...

Code works perfectly, but I guess that changes in 'user' template (as well as in any other built-in templates) is not good as changes have to be applied again after each PW upgrade.

Correct? If yes, what is the best way to avoid this?

Perhaps workaround could be to keep usernames/passwords/emails in admin template and create custom 'site-user' template which can keep any other fields ('tmp-pass' in this case). This also requires unique key to match PW user and 'site-user' in the code, and can be done with help of username or email field (must be added to 'site-user' template).

Please advice if logic regarding usage of admin templates is correct and workaround is optimal. Thanks! 

Link to comment
Share on other sites

That's not correct. Nothing you do will get overwritten on update you just replace /wire/ folder, unless you modify something in there you're save to change whatever template you wish and it will stay there.

  • Like 1
Link to comment
Share on other sites

Been using Ryans code for the login page and I'm finding I get a server error if the user enters a username which includes an @

the error seems to be coming from:

$username = $sanitizer->username($input->post->username);
$pass = $input->post->pass; // this line has nothing to do with the problem, just left it in for consistency
$u = $users->get($username);

When sanitizing the username, the value we get back is not loved by the $users selector.

The error is logged as:

2013-04-13 16:27:19    guest    http://127.0.0.1/login/    Error:     Exception: Unknown Selector operator: '' -- was your selector value properly escaped? (in C:\xampp\htdocs\processwire\wire\core\Selectors.php line 165)

For myself I didn't need the user to be able to enter @ as I'm not passing an email, therefore I've flipped out the sanitizer to use name instead, i.e.

$username = $sanitizer->name($input->post->username);

I assumed this was a bug with the username sanitizer, however if there's a code change I could make it would be great to hear.

  • Like 1
Link to comment
Share on other sites

$sanitizer->username() is a deprecated holdout from PW 2.0, which didn't store users as pages and email addresses were allowed as usernames. So that's a typo on my part as the username() call should have been $sanitizer->pageName(), as users are themselves pages. 

Link to comment
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.

×
×
  • Create New...