Jump to content

Redirect after login to original page


Vayu Robins
 Share

Recommended Posts

Hi.

I have a membersite that sends out emails to users with links to specific pages. When the user clicks on the link in the mail and the browser opens the site, the user is redirected to the login page. However, I would like for the user to be redirected back to the page they opened from their mail. I don't see how this can be done in Processwire.

I have a template and in the Access settings, I have chosen to redirect to the login page. There is on tag that I can include with {id}, but that returns the ID of the login page. I would like to have a tag that returns the ID of the original page the user has opened. Maybe a tag called {id_original} could be a way to solve it. Is there some other way I can filter the redirect process?

post-3258-0-86436500-1456396334_thumb.pn

Link to comment
Share on other sites

It will be interesting to see how this can actually happen (I'm not saying that there isn't a way to circumvent access security).

I have a few comments:

I have a template and in the Access settings, I have chosen to redirect to the login page. 

From the image you provided, this is not what you are attempting.  Unless you mean to go to another type of login page (other than the administrative login).  You then state that your purpose is to redirect to whatever page was linked in the email.

The fact that you have clicked "Yes" on the Access tab on the template means that you are detailing what the page security is going to be.  Anything other than Guest will restrict access to the page (making it viewable), if you are not already logged into the site.  To put it in another way, any page that has a template where the access tab has been activated will follow whatever permissions you have set in that tab.  If you had left the Access tab set to "No", then the page would inherit access from it's parent page.

You say that this is a membership site, so I would assume that access permissions are an integral part of the website's configuration.  In this case, everything works as it should, your credentials are checked for the page you want to access (link to).  

  • If you have access, you go to the page.
  • If you don't have access you either get a 404 page, goto the admin login page to login or go to another page (remember you then still need to have access to wherever you are being redirected to) that you have defined.

The only way you can do what you want is to have ProcessWire simply ignore the setup security and take the email addressee directly to whatever page is set in the email.

Link to comment
Share on other sites

Thanks for you reply cstevensjr!

I understand the confusion and I should have written something else in the settings page. My image was just to show what I wanted to explain, so that if it was possible to insert a tag {id_original}, then that would be great. I should correct what should be written in the inputfield. It should be something like "/login/?case={id_original}". That way I could access the page id after login and redirect back to the original page. Does that make more sense?

Link to comment
Share on other sites

Hhm, this may be only of less importance, and I hope, someone else will chime in with a good solution. But if not, I use a login and logout feature with the userswitcher of my ALIF module. If you are comfortable with module creation and hooks, you may have a look at it and pick up some code to build a small module. (Or you put a small code piece into the init.php or ready.php)!

The hook method:

https://github.com/horst-n/AdminLinksInFrontend/blob/master/AdminLinksInFrontend.module#L284

// if it is in a module, it can look like this:
    public function hookBeforeProcessLogin(HookEvent $event) {
        // early return, if it is not a link with the GET param id_original
        if(!$this->input->get('id_original')) return;
        
        // get the redirect URL
        $id = (int)$this->input->get('id_original'); // sanitize via typecasting
        $p = wire('pages')->get("id=$id");
        if(0 == $p->id) return; // it was not an existing / valid pageid
        
        // ?? maybe here you have to do additional validation to secure that the returned page is meant to be served
        // and that it is not one, the user has no access to, ... ??
        ...

        // if it is a valid page, redirect now
        $this->session->redirect($p->url);
    }

Not tested, written in the browser, no warranty, but hope it helps. :)

Link to comment
Share on other sites

I personally feel that this issue is best resolved by just letting the current system work as it should, challenge/verify credentials and then provide access to the linked page.  The whole problem revolves around whether the email user has access privileges on the website wherever you are trying to take them.

No matter what you do, you can't reliably guarantee that the email user is who you think they are.  Even the authentication or cryptographic nonce cannot guarantee that an unsecured email hasn't been compromised over an unsecure Internet. Ignoring that, with just the email link if you had a process where you could store the link, have them login and then somehow recover the page url and take them there.  Your problem again will be, do they have access permission to that linked page?

I guess you can cheat the system by having a hidden page within the member's secured area that has a page with a special template that allows Guest access.  That may get you to the page directly via an email link.

It's basically, Access Security 101.

Link to comment
Share on other sites

Thanks Horst, I will try to see if I can find a way to use your code snippet. :-)

Charles, I am not sure I understand what you are trying to explain. Sorry :-)

In the email the user receives, there is a link to a page, that one must be logged in (a member) to be able to see. If the user is not logged in and the user opens the link in a browser, then the user will be redirected to a login page. This is how it works now. What I need, is for the user to be redirected to the original page after login. If the user is not a member, then there will be no access, no matter what.

Link to comment
Share on other sites

Perhaps rather than initially redirecting them to the login page, you could simply add a login form to the page itself. You could do this manually in your template file, or make use of ProtectedMode (http://modules.processwire.com/modules/protected-mode/), either as is, or maybe you could lift some code to make something custom.

  • Like 2
Link to comment
Share on other sites

@Vayu_Robins: +1 for adrians module. That's the perfect fit for your needs. How could I not think of it? :huh: I use it myself on a site. :)

Actually, you might want to look at PageProtector (http://modules.processwire.com/modules/page-protector/) instead. It let's you control access to just specific pages and also lets you embed the login form into your template so the login form sits within the existing look of your page.

  • Like 1
Link to comment
Share on other sites

Thank you Adrian. I tried PageProtector, but it didn't work on my site. I don't know why though, but it was the part where inserting the login form on a template that didn't work. I ended up just adding a login form to the template, checking if the user is logged in or not.

Thanks everyone for chipping in with ideas and feedback!

  • Like 1
Link to comment
Share on other sites

@Vayu Robins - did you read through the PageProtector forum thread? @houseofdeadleg couldn't get it to work either, but I think he misunderstood what is required. Do you get any errors with DebugMode On or TracyDebugger installed?

Link to comment
Share on other sites

Thanks for asking Adrian.

I think I set it up correctly. In the "Login Template" I have chosen to use a template called "login.php". This is the code in that file:

$t = new TemplateFile( wire('config')->paths->templates . 'markup/login-form.php' );
include_once("./init.inc");
$headline = $page->get('headline|title'); 
$content = $loginForm.' '.$page->body. ' ' .$t->render();
include("./main.inc");

It's almost like the code in the init.inc file is not loaded, because all the variables in that file throw errors in main.inc

Link to comment
Share on other sites

I am not sure why it's not working for you. I have been playing around with a setup similar to yours and getting it to output. I am wondering if there are some issues around the way you are rendering the TemplateFile.

You say the the variables from the init.inc are throwing errors - do these go away if you don't use PageProtector, but otherwise the code is the same?

I also see that the TemplateFile is a login form, so it looks like you are already replicating what the module is trying to output with $loginForm?

Link to comment
Share on other sites

Why not just append a URL param redir=URL and redirect after successful login? The original URL could be stored in session too.

@tpr: Yes, you are right, this is already known as possible solution. see: https://processwire.com/talk/topic/12326-redirect-after-login-to-original-page/#entry114235

I think, @adrian is interested in why it is not working with his module, because it should be. ?! :)

  • Like 1
Link to comment
Share on other sites

@Adrian, I have also tried without my loginform and yes the errors go away when not using PageProtector. I will paste in the error I get here, maybe it makes some sense to you. 

Notice: Undefined variable: template_url in /Users/vayu/Sites/hunterapp.dev/site/templates/main.inc on line 453 Call Stack #TimeMemoryFunctionLocation 10.0037535928{main}( )../index.php:0 20.323619941048execute ( )../index.php:235 30.323719941400Wire->__call( )../index.php:235 40.323719941728Wire->runHooks( )../Wire.php:333 50.323719943872call_user_func_array:{/Users/vayu/Sites/hunterapp.dev/wire/core/Wire.php:398} ( )../Wire.php:398 60.323719945256ProcessPageView->___execute( )../Wire.php:398 70.358820182456render ( )../ProcessPageView.module:187 80.358820182640Wire->__call( )../ProcessPageView.module:187 90.358820182640Wire->runHooks( )../Wire.php:333 100.453420875128PageProtector->protectedCheck( )../Wire.php:459 110.454320878584wireRenderFile( )../PageProtector.module:280 120.454420882272render ( )../Functions.php:1062 130.454420882456Wire->__call( )../Functions.php:1062 140.454420882456Wire->runHooks( )../Wire.php:333 150.454420884408call_user_func_array:{/Users/vayu/Sites/hunterapp.dev/wire/core/Wire.php:398} ( )../Wire.php:398 160.454420884576TemplateFile->___render( )../Wire.php:398 170.454720925160require( '/Users/vayu/Sites/hunterapp.dev/site/templates/login.php' )../TemplateFile.php:182 180.456521111496include( '/Users/vayu/Sites/hunterapp.dev/site/templates/main.inc' )../login.php:62 assets/bootstrap/css/bootstrap.css" rel="stylesheet">
Link to comment
Share on other sites

I honestly don't know - I just tried replicating your setup with the "new TemplateFile" approach and it's working just fine.

Anyway, it sounds like you are not using this, so maybe we don't need to worry about it at the moment :)

Link to comment
Share on other sites

  • 1 year later...

Hi,

I had the same situation as the OP described: URL sent by email to go to a specific page after login.

I solved it with 2 small hooks that I added to a module. You could also add them to your admin.php or ready.php

My URL looks like .../?member=1222 where 1222 is the id of a user
1. hook adds a session variable before Login
 

$this->addHookBefore('ProcessLogin::execute', $this, 'setRedirectId');
	public function setRedirectId(HookEvent $event) {

		if($this->input->get('member')) {
			$this->session->set('goToMember', $this->sanitizer->int($this->input->get('member'));		
		}

	}

2. hook has the redirect logic and removes the session variable

$this->addHookAfter('Session::login', $this, 'loginRedirects');
	public function loginRedirects(HookEvent $event) {

		if($this->user->hasRole('certificationadmin') && $this->session->get('goToMember')) {
			$member = $this->pages->get($this->session->get('goToMember'));
			if($member && $member->id) {
				$this->session->remove('goToMember');
				$this->session->redirect($member->statusPageUrl); // statusPageUrl is a custom property for users that I added via another hook
			}
		}

	}

 

  • Like 1
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
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By ErikMH
      I’m new to Processwire. I’ve installed the current release version at my very-long-time (25 years) host, pair Networks. MySQL db is created. Installation process completed with no errors.
      I’m now trying to log in. Rather than taking the default `/admin` suggestion, I chose `/xyzzy`. When I go to `example.com/xyzzy`, PW displays a login screen, as expected. I enter the username (`xyzzy`) and password that I assigned (and copied and stored in 1Password) in the installation process (five words separated by hyphens). So far, so good.
      I would expect then to be taken to the admin pages. Or (if I got something wrong) to be given an error message. Instead, I’m taken to the URL `example.com/xyzzy/page/?login=1`, which as far as I can tell is exactly the same as the initial login page. No error is given.
      I grew so frustrated by this, that I deleted the entire installation and the MySQL database, re-downloaded PW, installed it again using a different username and password for the admin account.
      And I’m seeing exactly the same behavior. Time for me to ask you experts: WTF?
      Many thanks for any insights you may have....
       
    • By jploch
      Hey folks,
      currently Iam working on a website for one of my clients and I need some advice on how to approach this in PW.
      The website is for a company, that offers holiday houses in two locations. 

      The client wants the homepage to show the first location. Normally I just have a home template for the first page, but here the URL should reflect that you are in Location 1. So when you visit the URL casamani.com it should redirect to casamani.com/location-1. Not sure if this makes sense at all.

      Whould it be bad for SEO and performance reasons to redirect home to the Location-1 page?
      Another approach would be to render the Location-1 template on the home template or do an include like discussed here.
      Here is how the tree looks:
      – Home
      – Location 1 (Homepage)
           – Creation
           – Adventure
           – Sustainability
      – Location 2 
           – Creation
           – Adventure
           – Sustainability

      Thanks for looking into this!
    • By Marvin
      Hi,
      I'm still new at processwire, i want to ask, i was create a website with sign in system, but i want to add a access roles/permission for each user at my website. For now, i just can create a login user without any permission and the user data became as a pages in my processwire.
      Here i attach my code for login
      <?php $note = $note2 = $hidden =""; if($input->get->id == "logout") { $session->remove('login_id'); } if($input->post->submit) { $email = $sanitizer->email($input->post->email); $pass = $sanitizer->text($input->post->pass); $result = $pages->find("email=$email, text_1=$pass"); if(!$email || !$pass) { $note = "Data belum lengkap"; } else { if($result->count > 0) { $session->login_id = "$result"; $hidden = "style = 'diplay:none'"; $url=$pages->get("/files/")->httpUrl; header("Location:$url"); die(); } else { $note = "Akun tidak ditemukan"; } } } ?> And this code for login form
      <div class="frow-container"> <div class="frow centered mt-50"> <div class="col-md-1-3"> <div class="box p-40 shadow-light"> <h2 class="mb-20 text-center" <?=$hidden?>>Database Partitur<br>GII HIT</h2> <form method="post" <?=$hidden?>> <label>Username <input type="text" name="email"></label> <label>Password <input type="password" name="pass"></label> <input type="submit" name="submit" value="Masuk"> </form> <p class="notif"><?=$note;?></p> <div class="text-center"><?=$note2;?></div> </div> </div> </div> </div> Just for remember, my user data now is a pages, and i cannot give any permission to user data.
      Thank you very much for help.
    • By kyksh
      Hi!
      I need users to login by their email address. This works when I change the value in ProcessLogin.module
       122     protected $useEmailLogin = null;
      to
      122     protected $useEmailLogin = true;
      What would be a recommended way to enable this?
      There's this line in ProcessLogin.module:
        15  * @property bool|int $allowEmail Whether or not email login is allowed (0|false=off, 1|true=Yes, 2=Yes or name also allowed)
      But I can't figure out how to set this. I tried next to $useEmailLogin in ProcessLogin.module and in config.php, but neither takes effect.
      BTW I tried module LoginWithEmail but it seems outdated. My PW version is 3.0.165
    • By theoretic
      Hi guys and ladies! And thanks for Processwire!
      It appears i've got an interesting issue concerning the template-settings-based PW redirects dealing with access control. Any PW template has some access control options i.e. "Login redirect URL or page ID to render". If this option is used for a page having a template with this option filled, a redirect will occur if user is not logged in and/or has insufficient access rights.
      I like to hook PW events. In one of my current projects i decided to write an addHookBefore('Session::redirect', ...) which should store the page we are being redirected from. With "regular" redirects like $session->redirect('/somewhere/') this hook works like a charm. But it was strange to see that it doesn't work with the template-settings-based redirect.
      I'm too dumb to dive deep inside PW and to examine the whole PW session mechanism. But it could be rather logical if ANY redirect ( no matter template-settings-based or using $session->redirect() ) could be hooked in the same manner.
      Okay okay i can forget about template-settings-based redirect and write my own. Just a couple of lines of code, and it works. But it's less elegant than hooking the template-settings-based redirects.
      So am i missing something? It this behavior a bug, or is it intended by PW team? Thanks in advance for any comment!
×
×
  • Create New...