Jump to content

How to redirect the user back to desired URL after login page?


tires
 Share

Recommended Posts

Hi!

I made a little intranet with processwire.

If there is a new article a mail containing the URL (https://mysite.com/article/name-of-my-article/) is sended to each user.
If the user klicks on the url and he is not already logged in he is now redirected to the login page (in this case a frontend login with Login/Register module).
After login he is redirected to the start page but not to the URL from the mail.

What is the most simple way to get a proper redirect to the expected URL?
Do i have to work with a cookie? Where do i have to write and read this cookie?

Thanks!

Link to comment
Share on other sites

You can write a simple hook, and to redirect to a specific url, you can set the url in the user session, once logged, redirect and unset it. An idea could be to set a GET variable in the link you send to your users so it will work only for theses links, then do the logic in the hook (about checking for the existing GET var and setting the url in the session).

Check this thread for the hook :

 

  • Like 2
Link to comment
Share on other sites

Thanks!

Do you have any idea how to avoid a GET var and just work with the normal URL?
And where to grab this URL so i could redirect after login?
Do i need another hook for this purpose?

This test hook doesn't output a segment at all:

$this->addHookBefore('ProcessLogin::buildLoginForm', function(HookEvent $event) {
  $segment = $this->wire('input')->urlSegment1();
  echo "This is my" . $segment;
});

 

Link to comment
Share on other sites

@tires the hook need to be Session::loginSuccess - the one given by @adrian - to redirect the user, after he log in. You can write the target url in the session, and you do not really need the GET variable.

But as I said in the first idea, if you need to differentiate a user which come from the mailed url, you "have" to give a GET variable or a segment. If you do not do that, the url set in the session will be for all users. It might not be an issue for you.

  

5 hours ago, tires said:

And where to grab this URL so i could redirect after login?

I all needed template, just set $page->url in the session. Apply logic there. And as I said, without distinction, it will apply for all users.

 

  • Like 2
Link to comment
Share on other sites

@tires, when redirecting to a login URL from a page that has restricted view access PW has a built-in option to include the ID as a GET variable.

image.png.04f6d398522969c2617ca6c1b9fbe79a.png

You can make use of this ID number in a hook after successful login to get the page that the user was trying to access and then redirect back to its URL.

  • Like 3
Link to comment
Share on other sites

  • 2 weeks later...

Many thanks to both of you!

I solved it this way and put the following hooks in my site/ready.php ...

First hook to grab the URL:

$this->addHookBefore('ProcessLogin::buildLoginForm', function(HookEvent $event) {
   // --- Split URL --- //
  $actual_link = explode('/',(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
  // --- Putting the last i.e. fifth part of the URL in a session cookie "weiterleiter" --- //
  $this->wire('session')->set('weiterleiter', $actual_link[5]);
});

Second hook to redirect after login:

$this->addHookAfter('Session::loginSuccess', null, function($event) {   
  // --- Get session cookie "weiterleiter" and write it in $weiter --- //
  $weiter = $this->wire('session')->get('weiterleiter');

  // --- If the $weiter is not empty add the path and write it in $url  --- //
  if(!empty($weiter)) $url = "artikel/".$weiter;

  // --- Redirect to the URL --- //
  $this->wire('session')->redirect($url);

  // --- Delete the session-Cookie  ---//
  $this->wire('session')->remove('weiterleiter');
});

That works for me!

Is there a smarter way to do this?
Or a smarter way to get the url by segments?

  • Like 1
Link to comment
Share on other sites

On 10/11/2022 at 5:39 PM, tires said:

Do you have any idea how to avoid a GET var and just work with the normal URL?

Hi,

just my two cents 🙂
for a front-end login page, url segments could be your friends (the page to be redirected id, name or whatever you want)
a little regex to keep them safe, it wouldn't change the login url and you could grab it like a var, same thing as what @bernhard has highlighted for the pw native login

have a nice day

  • Like 2
Link to comment
Share on other sites

@tires, if it's working for you then great, and I don't really get how URL segments relate to what you're doing, but what I was suggesting is to use hooks like this:

// Add return GET variable to form action URL so it's available after the login form is submitted
$wire->addHookAfter('LoginRegister::buildLoginForm', function(HookEvent $event) {
	/** @var InputfieldForm */
	$form = $event->return;
	$return_id = (int) $event->wire()->input->get('return');
	if($return_id) $form->action .= "?return=$return_id";
});

// If login is successful...
$wire->addHookAfter('LoginRegister::loginSuccess', function(HookEvent $event) {
	$return_id = (int) $event->wire()->input->get('return');
	// ...and there is a return page ID...
	if($return_id) {
		// ...check that the user can view the page and if so redirect back to it
		$return_page = $event->wire()->pages->get($return_id);
		if($return_page->id && $return_page->viewable()) {
			$event->wire()->session->location($return_page->url);
		}
	}
});

 

  • Like 4
Link to comment
Share on other sites

6 minutes ago, Robin S said:

and I don't really get how URL segments relate to what you're doing

Hi @Robin S

let's imagine this https://foo.com/userlogin/3025
isn't it easy to grab 3025 and, if the login is successful, redirect the user to $pages->get(3025)->url;?
would be the same with a page name and easy to change each time the page you need to redirect to does

just a simple question 🙂

have a nice day

Link to comment
Share on other sites

Many thanks to all of you!

5 hours ago, Robin S said:

I don't really get how URL segments relate to what you're doing

I thought it would be useful to use the processwire functions (i.e. segments) and I did not want to change the url.
Because if someone kicks on the link in the mail and is already logged in the url would have to be changed again ... from the url with get to the regular one.
 

Link to comment
Share on other sites

7 hours ago, tires said:

I did not want to change the url.
Because if someone kicks on the link in the mail and is already logged in the url would have to be changed again ... from the url with get to the regular one

I think perhaps you missed the point of my earlier post:

When you use this approach you don't need a different URL to the regular one. If a non-logged-in visitor tries to view a page that you must be logged in to view then they get redirected to your custom login form and the ID of the page they tried to view is preserved in a GET variable (you could use a URL segment to hold the ID instead of a GET variable but I can't see a reason why that would be preferable).

So let's say I try to view a restricted page at https://www.websitedomain.com/articles/i-love-processwire/
It doesn't matter how I got the URL - it could have been in an email, or a browser bookmark, or whatever.

If I'm not logged in when I try to view it and the page template is configured like I showed in my earlier post then I'm automatically redirected to https://www.websitedomain.com/my-login-page/?return=1234

And if the hooks I showed are in ready.php then after I login I'm automatically returned to https://www.websitedomain.com/articles/i-love-processwire/

  • Like 2
Link to comment
Share on other sites

Hi,

@Robin S is right, my url segment idea is not necessary but just a simple way to keep the page id alive 🙂
now, honestly, when i have to do what you described, as much as i love coding, hooks and all what pw gives us i would probably use session vars the way @Robin S shows in the hook but simply in the login page code, maybe because i'm too used to doing this kind of thing without the help of pw...
- if the user arrives unlogged on the page, i would set a session var with the id of the page and then redirect to the login page (instead of login/pageid that doesn't need this session var)
- if the login is successful, simply use pw redirection abilitiy to the page the id is in the session destroying the var that isn't useful anymore

but using the login/register plugin @Robin S's hook is more the pw way of working than my savage 'manage your life on your own' solution 😄

have a nice day

  • Like 1
Link to comment
Share on other sites

13 hours ago, Robin S said:

When you use this approach you don't need a different URL to the regular one. If a non-logged-in visitor tries to view a page that you must be logged in to view then they get redirected to your custom login form and the ID of the page they tried to view is preserved in a GET variable (you could use a URL segment to hold the ID instead of a GET variable but I can't see a reason why that would be preferable).

 

You are absolutely right!
But the GET variable is not absolutely necessary if i understand it right.

21 hours ago, tires said:

I thought it would be useful to use the processwire functions (i.e. segments)

Is there any way to get the last part of the URL via segments instead of this wild explode('/' ...
Or can i not use segments in this context?

Link to comment
Share on other sites

hi,

the pw way on top of a page

$input->urlSegment1

you can use various functions to check if there is one or no, for example

if ( strlen($input->urlSegment1)) $foo = ...

and of course validate if the segment is an authorized one, regex for example, beginning with the segment you accept in the model parameters (i nearly always use regex, i.e

regex:^[0-9]{1,5}$ //or 6,7... depending on how many pages you'll have :)

that will check the segment looks like a page id, if not, 404...

now, coming to hooks, never did this, il let @Robin S answer this, he knows pw and hooks far better than i do 😄

have a nice day

  • Like 1
Link to comment
Share on other sites

As i mentioned before i didn't get any result in my hook if i try it with segments.

On 10/11/2022 at 5:39 PM, tires said:
$this->addHookBefore('ProcessLogin::buildLoginForm', function(HookEvent $event) {
  $segment = $this->wire('input')->urlSegment1();
  echo "This is my" . $segment;
});

Or is there something wrong?

 

 

Link to comment
Share on other sites

Now I run into another problem.

I would like to use the redirect in a website where i use the login/register module.

According to my devtools in firefox the initially URL (https://mysite.com/article/name-of-my-article/) is redirected to the frontend login form (https://mysite.com/) with a 301.

I have no idea how to write the hook to grab the URL and set the cookie.
In this hook i don't work:
$this->addHookBefore('ProcessLogin::buildLoginForm', function(HookEvent $event) ...

Link to comment
Share on other sites

  • 4 weeks 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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...