Jump to content

Custom Login


Frank Vèssia

Recommended Posts

As it says: "use pageName instead"

/**
* Format required by ProcessWire user names
* 
* #pw-internal
*
* @deprecated, use pageName instead.
* @param string $value
* @return string
*
*/

public function username($value) {
    return $this->pageName($value); 
}

 

  • Like 3
Link to comment
Share on other sites

  • 6 months later...

Hello!

If this can help someone, this is how I build my login form:

// Sign In controller
<?php namespace ProcessWire;

/**
 * Class SignIn
 *
 * @package ProcessWire
 */
class SignIn {

	/**
	 * Render
	 *
	 * @return string
	 *
	 */
	public function render(): string {
		$input = wire("input");
		$template = $this->getSignInTemplate();

		if($input->post("login_submit")) {
			// taken from ProcessLogin->execute();
			$name = wire('sanitizer')->pageName($input->post("login_name"));
			$pass = substr($input->post("login_pass"), 0, 128);

			if(wire('session')->login($name, $pass)) {
              	// Successful login 
				wire("session")->redirect("");
			} else {
                // Login failed
				$template->set("error", "login failed!");
				$template->set("sign_in_form", $this->signInForm());
			}
		} else {
			// set template variables
			$template->set("sign_in_form", $this->signInForm());
		}

		return $template->render();
	}

  	/**
    * @return string
    */
	protected function signInForm() {
		$input = wire("input");
		$modules = wire("modules");

		// create a new form field (also field wrapper)
		$form = $modules->get("InputfieldForm");
		$form->action = "./";
		$form->method = "post";
		$form->attr("id+name", 'sign-in-form');

		$f = $modules->get('InputfieldText');
		$f->set('label', "Username"); // Login form: username field label
		$f->attr('id+name', 'login_name');
		$f->attr('class', 'Name');
		$f->attr('value', $input->post("login_name"));
		$f->collapsed = Inputfield::collapsedNever;
		$form->add($f);

		$f = $modules->get('InputfieldText');
		$f->set('label', "Password"); // Login form: password field label
		$f->attr('id+name', 'login_pass');
		$f->attr('type', 'password');
		$f->attr('class', 'Pass');
		$f->collapsed = Inputfield::collapsedNever;
		$form->add($f);

		$f = $modules->get('InputfieldSubmit');
		$f->attr('name', 'login_submit');
		$f->attr('value', "Sign in"); // Login form: submit login button 
		$form->add($f);

		return $form->render();

	}
	/**
	 * Get Sign In template
	 *
	 * @return \TemplateEngine
	 *
	 */
	protected function getSignInTemplate(): \TemplateEngine {
		return wire("factory")->load("/components/sign-in");
	}

}

 

Thanks :).

 

  • Like 3
Link to comment
Share on other sites

  • 7 months later...

I'm using @Soma 's nice code for a custom login & it's working great on IE, Edge & FF (thanks!) but on Chrome I just get a blank page after the login.

After refreshing the page the password protected page loads OK.

I've no plugins on Chrome blocking page reload etc.

The pages has a template with access denied to guest, but set to allow access via a specific role/user with access.

The template for the page is set to redirect the user to the login page when a user attempts to access.

Not sure if this is significant, but the password protected page url stays the same when the the login page is presented to the user...

Has anyone else come across this (Chrome issue)? Thanks

Edited by dab
Link to comment
Share on other sites

..I did some more digging & identified that the chrome issue happens when I use:

$content.="<form action='./' method='post'>";

rather than @Soma's code  which was originally:

$out = '<form action="./?id='.$requested_id.'" method="post">';

Note: I had to change some of the quotes on  @Soma 's post to:

$content.="<form action='./?id=".$requested_id."' method='post'>";

as the original gave a parse error with delayed strategy templates.

but the resulting html output from my edit is:

<form action='./?id=0' method='post'>

So something is not quite right with the code, as the requested id is not being picked up from the code...

if ($user->isLoggedin()) {
 $content.="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 {
  $content.="Login Failed. Please try again.";
	}
 }

$content.="<form action='./?id=".$requested_id."' method='post'>";
$content.="<label for='name'>Usename:</label>
			<input type='text' name='user' id='name'/>";
$content.="<label for='password'>Password:</label>
		   <input type='password' name='pass' id='password'/>";	
$content.="<input type='submit' name='submit' value='Login' class='button fit special' />";
$content.="</form>";
}

Not sure what to try next....

Link to comment
Share on other sites

4 hours ago, dab said:

but the resulting html output from my edit is:


<form action='./?id=0' method='post'>

A page ID of zero means a NullPage - that's not a valid page you can redirect to if login is successful.

When setting the value of $requested_id you should set a fallback value (e.g. "1", the home page) if no id is present as a GET variable.

Something like: 

$requested_id = (int) $input->get->id ?: 1;

 

  • Like 2
Link to comment
Share on other sites

@Robin S, thanks kindly for your suggestion. I tried this, but instead, the logged in user get redirected to "home" on login instead of the requested page.

The html output is

<form action='./?id=1'

What I don't understand is why the "get" $request_id is not working....

// get id var from request
 $requested_id = (int) $input->get->id;

I'll see if I can find anything else on the forums....

With thanks.

Link to comment
Share on other sites

7 hours ago, dab said:

What I don't understand is why the "get" $request_id is not working....

If it's not working then the GET variable "id" must not be present in the URL of the form page. How are you adding this GET variable when you prevent access to the protected page and redirect to the login form? Typically there are two ways you would add the variable:

1. Using the "Redirect to another URL" option in the Access tab of the template.

2018-03-05_094904.png.fa6da34fe9743f148847a59dbdbe6c33.png

2. Using your own logic in the template files of protected pages, e.g.

if(!$user->isLoggedin()) echo "<p>Please <a href='/login/?id=$page->id'>log in</a> to access this page.</p>";

 

Link to comment
Share on other sites

Many thanks @Robin S, I was using the first option, initially as just the page id (obviously the request_id wasn't getting called, & then I tried "/login?return={id}" - but clearly the syntax was wrong.

Thanks, I've spent hours going through the the forums & trying various combinations of code - I'm so grateful for your help.

Link to comment
Share on other sites

  • 3 weeks later...
13 minutes ago, Autofahrn said:

Is there a chance to get the page name instead of its id for the redirect URL entry? Using {name} obviously does not work. I'd somehow prefer to not see my page numbers in the url.

Nope, a name wouldn't be unique throughout the system. I don't see a problem at all to see the page ID.

Link to comment
Share on other sites

Sure, the name alone is not enough, I had the url in mind. But that of course would need some more encoding. Sometimes I'm replacing pages by renaming them so the url stays the same but referring to a different page. Its more a principle... ;-)

Link to comment
Share on other sites

  • 3 years later...

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...