Frank Vèssia Posted February 25, 2011 Share Posted February 25, 2011 It's possible to create a custom login page like a template? 1 Link to comment Share on other sites More sharing options...
ryan Posted February 25, 2011 Share Posted February 25, 2011 Absolutely! Here is a simple, but functional example for both login and logout templates. You would want to replace the markup with your own markup or includes. Likewise you'd want to change the redirects to redirect to whatever page you want them to go to after completing a login. /site/templates/login.php: <?php if($user->isLoggedin()) { // user is already logged in, so they don't need to be here $session->redirect("/somewhere/"); } // check for login before outputting markup if($input->post->user && $input->post->pass) { $user = $sanitizer->username($input->post->user); $pass = $input->post->pass; if($session->login($user, $pass)) { // login successful $session->redirect("/somewhere/"); } } ?> <html> <head> <title>Login</title> </head> <body> <form action='./' method='post'> <?php if($input->post->user) echo "<h2 class='error'>Login failed</h2>"; ?> <p><label>User <input type='text' name='user' /></label></p> <p><label>Password <input type='password' name='pass' /></label></p> <p><input type='submit' name='submit' value='Login' /></p> </form> </body> </html> /site/templates/logout.php: <?php $session->logout(); ?> <html> <head> <title>Logout</title> </head> <body> <h1>You have logged out</h1> </body> </html> 19 Link to comment Share on other sites More sharing options...
Frank Vèssia Posted February 25, 2011 Author Share Posted February 25, 2011 Thanks as always 1 Link to comment Share on other sites More sharing options...
renobird Posted May 7, 2012 Share Posted May 7, 2012 Ryan, Thanks this gave me a great place to start. I thought I'd share the version I created in case anyone finds it useful. • Single template for the login/logout. • Automatically redirects the user back to whatever page they originally requested after they login. ./includes/login.php <?php // Handle logouts if($input->get->logout == 1) { $session->logout(); $session->redirect($page->path); } // If they aren't logged in, then show the login form if(!$user->isLoggedin()){ // check for login before outputting markup if($input->post->user && $input->post->pass) { $user = $sanitizer->username($input->post->user); $pass = $input->post->pass; if($session->login($user, $pass)) { // login successful $session->redirect($page->path); } else { $session->login_error = 'Login Failed. Please try again, or use the forgot password link below.'; } } ?> <!DOCTYPE HTML> <html lang="en"> <head> <title>Custom PW Login</title> </head> <body> <form action='./' method='post'> <div class="login"> <? if($input->post->user && $input->post->pass) { echo "<p class='error'>" . $session->login_error . "</p>"; }?> <p><input type='text' id="user" name='user' placeholder='Username'/></p> <p><input type='password' id="pass" name='pass' placeholder="Password" /></p> <p><input type='submit' class="btn" name='submit' value='Login' /></p> </div> </form> </body> </html> <? die(); // don't go any further if not logged in } // end !logged in ?> In any template you wish to protect: <? require("./includes/login.php");?> To trigger a logout: <a href="?logout=1">Logout</a> Note: I'm using the HTML5 placeholder attribute. Browser support is not 100%. You may want to use labels instead, or use some jQuery (like I did) to add the placeholder text for browser that don't support it. SideNote: How do you get code indents to stick when posting? I'm having to go back and add spaces to each line. I use tabs when coding. 17 Link to comment Share on other sites More sharing options...
ryan Posted May 8, 2012 Share Posted May 8, 2012 Thanks for posting Renobird. I'm confused on this section: if($session->login($user, $pass)) { // login successful $session->redirect($page->path); $error =""; $session->set($error, ""); } else { $error =""; $session->set($error, "Login Failed. Please try again, or use the forgot password link below."); } // ... further down echo "<p class='error'>".$session->get($error)."</p>"; It seems like that is just setting a blank session variable? Are you sure you didn't mean for it to be like this? if($session->login($user, $pass)) { // login successful $session->set("error", ""); // note: moved this above the redirect $session->redirect($page->path); }else { $session->set("error", "Login Failed. Please try again, or use the forgot password link below."); } // ... further down echo "<p class='error'>".$session->get('error')."</p>"; How do you get code indents to stick when posting? I'm having to go back and add spaces to each line. I use tabs when coding. Good question--I have no idea. I've been trying to figure this one out for awhile. I have to paste any code in my plain text editor, then manually indent everything with 4 spaces. This editor appears to ignore tabs. Pete's been doing a great job of installing updates for us here, so we'll very likely see improvements here as the IP.Board developers make them. 1 Link to comment Share on other sites More sharing options...
renobird Posted May 8, 2012 Share Posted May 8, 2012 Hi Ryan, Nice catch. Yeah, no sense setting a session variable after the redirect. That entire if/else had a bunch of stuff I was commenting in/out while I was testing, I did a poor job of cleanup. I updated my code above, so it's correct for anyone that uses it. 2 Link to comment Share on other sites More sharing options...
ryan Posted May 9, 2012 Share Posted May 9, 2012 Thanks for updating your code. Just one more thing there that I don't understand are these lines: $session->set($error, ""); $session->set($error, "Login Failed. Please try again, or use the forgot password link below."); echo "<p class='error'>".$session->get($error)."</p>"; As far as I can tell, $error is an undefined/empty variable. Unless I'm misunderstanding something, shouldn't all of the $error instances instead be 'error' ? like this: $session->set('error', ""); $session->set('error', "Login Failed. Please try again, or use the forgot password link below."); echo "<p class='error'>".$session->get('error')."</p>"; Link to comment Share on other sites More sharing options...
renobird Posted May 9, 2012 Share Posted May 9, 2012 Hi Ryan, Session variables and error handling aren't things I'm all that good at, so any guidance is appreciated. I'm just working off the cheatsheet and hacking my way around. I realize now that I initially had $error =""; in there because I thought that was the proper way to avoid the undefined variable. When I tried setting it up like you suggested: if($session->login($user, $pass)) { // login successful $session->redirect($page->path); }else { $session->set('error', ""); $session->set('error', "Login Failed. Please try again, or use the forgot password link below."); } echo "<p class='error'>".$session->get('error')."</p>"; I get this error if I enter an incorrect password more than once. Warning: Invalid argument supplied for foreach() in /x/xxxx/xxxxxxxx.edu/htdocs/wire/core/Session.php on line 60 However, when I do it this way it seems to work properly. if($session->login($user, $pass)) { // login successful $session->redirect($page->path); }else { $error =""; $session->set($error, "Login Failed. Please try again, or use the forgot password link below."); } echo "<p class='error'>".$session->get($error)."</p>"; I'm sure there is a best practice for this, I just don't know what it is, so I fiddled around until I got it to work. Link to comment Share on other sites More sharing options...
ryan Posted May 9, 2012 Share Posted May 9, 2012 I think the problem might be that $session already keeps it's own 'error' function and variable, which is an array. So it might just be a matter of naming and using something like 'login_error' rather than 'error'. Your current solution works because it's likely resolving to a session variable named blank or "0". But if you tried to do something similar anywhere else, then you'd have unpredictable behavior. As a result, I think it's best to give $session an actual variable name that you want to use, like this: $session->login_error = 'your message here'; and retrieve it like this: echo '<p>' . $session->login_error . '</p>'; using set() and get() is also fine, but not necessary. 1 Link to comment Share on other sites More sharing options...
renobird Posted May 9, 2012 Share Posted May 9, 2012 Thanks Ryan, Much appreciated. I'll test on my site and then update the code example accordingly. 1 Link to comment Share on other sites More sharing options...
renobird Posted May 9, 2012 Share Posted May 9, 2012 Yep, works great! In case anyone is following along, my original example is updated and working correctly. Thanks Ryan! 7 Link to comment Share on other sites More sharing options...
onjegolders Posted June 1, 2012 Share Posted June 1, 2012 Thanks Renobird, this code has just helped me out! 1 Link to comment Share on other sites More sharing options...
Lars282 Posted June 11, 2012 Share Posted June 11, 2012 Hey, I am trying to use renobird's code above, but can't get the redirect to work properly. I call e.g. /login/?id=1009 and after a successful login: if ($session->login($user, $pass)) { // login successful $session->id = $input->get('id'); $session->redirect($pages->get($session->id)->path); } I discovered that the problem is that my $input->get('id') is empty ... but don't understand why and can't seem to fix it. Already tried using something else than id in case that was a system reserved name, but didn't make any difference. Lars Link to comment Share on other sites More sharing options...
ryan Posted June 11, 2012 Share Posted June 11, 2012 Make sure that you aren't outputting anything the call to $session->redirect(). In order for a redirect to work, it must happen before any output is sent. Also, make sure to sanitize your 'id' variable by typecasting it to an integer: $session->page_id = (int) $input->get('id'); Link to comment Share on other sites More sharing options...
Lars282 Posted June 12, 2012 Share Posted June 12, 2012 Thanks ryan, but still can't get it to work. My login file starts with this: <?php if ($user->isLoggedin()) { $out = 'You are already logged in.'; } else { if ($input->post->user && $input->post->pass) { $user = $sanitizer->username($input->post->user); $pass = $input->post->pass; if ($session->login($user, $pass)) { // login successful $i = (int) $input->get->id; $t = $pages->get($i)->path; $session->redirect($t); } else { $out = 'Login Failed. Please try again.'; } } $out = '<form action="./" method="post">'; $out .= '<input type="text" name="user" value="Username" />'; $out .= '<input type="password" name="pass" value="Password" />'; $out .= '<input type="submit" name="submit" />'; $out .= '</form>'; } ?> But the redirect after successful login still doesn't work. Any ideas? Thanks! Link to comment Share on other sites More sharing options...
Soma Posted June 12, 2012 Share Posted June 12, 2012 What does not work? Can you please provide more infos? Any errors? Debug enabled? As Ryan said, the session redirect doesn't work if anything is already rendered before your code. I don't think this code is the only there is. If this code is included in some or has some header.inc that already has html code it will not work. Link to comment Share on other sites More sharing options...
Lars282 Posted June 12, 2012 Share Posted June 12, 2012 This is the very beginning of the login page template, header etc only comes after it, but assumed that what comes after is irrelevant for the redirect? After I login successfully, it only shows a blank page with no content on it, no errors. Link to comment Share on other sites More sharing options...
Soma Posted June 12, 2012 Share Posted June 12, 2012 Ah ok , have you tried to debug anything yet? For example where does the id come from? Output the path you are redirecting, is it correct? Link to comment Share on other sites More sharing options...
diogo Posted June 12, 2012 Share Posted June 12, 2012 I also don't understand where the id comes from. And where is it supposed to redirect to? Link to comment Share on other sites More sharing options...
ryan Posted June 12, 2012 Share Posted June 12, 2012 Use something other than $user for this: $user = $sanitizer->username($input->post->user); That overwrites the $user API variable in your template file, so better to use something like $username or $name or the like. It's probably not the issue here, but still something to fix just for good measure. After I login successfully, it only shows a blank page with no content on it, no errors. What is the URL in your browser window? When you access that URL independently of a login, do you get something different? Link to comment Share on other sites More sharing options...
Lars282 Posted June 13, 2012 Share Posted June 13, 2012 The url to login is something like /login/?id=1009. When a page requires a login, it redirects to this with the id being it's own id. After a login, this should redirect back to the previous page. @ryan: what do you mean with independently of a login? Link to comment Share on other sites More sharing options...
Soma Posted June 13, 2012 Share Posted June 13, 2012 Ryan was talking about the URL when you logged in, refering to your "blank" page. Anyway, it looks to me as the id from the url isn't submited by the form. A simple debug "echo $input->get->id;" and commenting out the redirect would show that there's no id. So I'd guess, the form action should contain the id so it gets submited by the url. 1 Link to comment Share on other sites More sharing options...
Soma Posted June 13, 2012 Share Posted June 13, 2012 Try something like this: <?php if ($user->isLoggedin()) { $out = 'You are already logged in.'; } else { // get id var from request $requested_id = (int) $input->get->id; if ($input->post->user && $input->post->pass) { $user = $sanitizer->username($input->post->user); $pass = $input->post->pass; if ($session->login($user, $pass)) { // login successful $t = $pages->get($requested_id)->path; $session->redirect($t); } else { $out = 'Login Failed. Please try again.'; } } $out = '<form action="./?id='.$requested_id.'" method="post">'; $out .= '<input type="text" name="user" value="Username" />'; $out .= '<input type="password" name="pass" value="Password" />'; $out .= '<input type="submit" name="submit" />'; $out .= '</form>'; } Link to comment Share on other sites More sharing options...
Lars282 Posted June 18, 2012 Share Posted June 18, 2012 Thanks Soma - very stupid of me! Link to comment Share on other sites More sharing options...
Soma Posted August 28, 2012 Share Posted August 28, 2012 SideNote: How do you get code indents to stick when posting? I'm having to go back and add spaces to each line. I use tabs when coding. Just saw this note of yours. When I have code I copy from editor I first switch tabs to spaces. In Sublime2 I can do this with one click in status bar. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now