Jump to content
adrianmak

any good way to redirect to original url from a custom login form ?

Recommended Posts

This is my original question asking for access control for a template

https://processwire.com/talk/topic/8847-redirect-to-a-url-in-the-access-tab-of-a-template/

Eventually, as of Soma suggestion, I implemented access control and redirection in template itself.

The problem is after a sucessful login, the $session ->redirect method only destinate to one assigned url (in my case it is the homepage).

Reading the api doc, the session redirect provide just a simple url redirection. NO MORE functionality provided.

Then I append a GET variable on redirect url

a page template  required a specific user role privilege

<?php

if (!$user->isLoggedin()) {
    /* get current page id for page redirection after a successful login */
    $pageId = $page->id;
    $session->redirect(($pages->get("template=login")->url . "?redirect=" . $pageId));   
} 

/* required user with role registered to view this template */
if ($user->hasRole("registered")) {
    $page->title;
    $page->body;
} else {
    $page->body = "Your account do not have enough access privileges to view this page.";
}
include('./main.php');

login form template

<?php
$pageID = $_GET["redirect"];

    $lang = ($user->language->name == 'default') ? '' : $user->language->name . '/';
    if ($user->isLoggedin()) {
        $session->redirect($config->urls->root . $lang);
    }

    if ($input->post->user && $input->post->pass) {
        $username = $sanitizer->username($input->post->user);
        $password = $input->post->pass;
        $pageID = $input->post->redirect;
        $redirectPage = $pages->get($pageID)->url;

        try {
            if ($session->login($username, $password)) {
                if ($redirectPage) 
                    $session->redirect($redirectPage);

                $session->redirect($config->urls->root . $lang);
            } else {
                $error = "Wrong username or password. Login failed.";
            }
        } catch (Exception $e) {
            $error = $e->getMessage();
        }        
    }

$form_title = __("Sign In");
$form_user = __("User");
$form_pass = __("Password");
$form_submit_btn = __("Sign in");
$form_error =  __("Login failed");


$page->title = "User Login";
$page->body .= "
<div class='container'>
    <div class='col-md-12'>
        <div class='login-box'>
        <div class='panel panel-default'>
            <div class='panel-heading'>
                <h3 class='panel-title'><span class='lock-icon'></span><strong>$form_title</strong></h3>
            </div>
            <div class='panel-body'>
                <form role='form' action='./' method='post'>
                    <div class='message-error'>$error</div>
                    <input type='hidden' name='redirect' value=$pageID />
                    <div class='form-group'>
                        <label for='user'>$form_user</label>
                        <input type='text' name='user' id='user' class='form-control' placeholder=$form_user />
                    </div>
                    <div class='form-group'>
                        <label for='pass'>$form_pass</label>
                        <input type='password' name='pass' id='pass' class='form-control' placeholder=$form_pass />
                    </div>
                    <button type='submit' class='btn btn-sm btn-primary'>$form_submit_btn</button>
                </form>
            </div>
        </div>
        </div>
    </div>
</div>
";

include('./main.php');
?>

Retrieve the original url from the GET variable and  store in a form hidden field.

When  a successful login, checking this variable, if null , redirect to homepage or otherwise to that url


is it secure to implement in this way ?

Share this post


Link to post
Share on other sites

Your method seems secure enough. You are after all not sending a 404, so your user already knows that the url that they originally requested exists.

Another method is to use the session to store the redirect url. So in the restricted page you would do:

if (!$user->isLoggedin()) {
    // Store requested url in the session, then redirect
    $session->set('redirect', $page->url);
    $session->redirect($pages->get('template=login')->url);
}

and on the login page you could have

// Edit: This code is not correct as-is, please note Soma's post below including the try-catch block around the login code!

<?php

    if ($user->isLoggedin()) {
        $session->redirect($pages->get('/')->url);
    }

    if ($input->post->user && $input->post->pass) {
        $username = $sanitizer->username($input->post->user);
        $password = $input->post->pass;

        if ($session->login($username, $password)) {
            if ($redirectUrl = $session->get('redirect')){
                $session->remove('redirect');
                $session->redirect($redirectUrl);
            } else {
                $session->redirect($pages->get('/')->url);
            }
        } else {
            $error = "Wrong username or password. Login failed.";
        }
    }

  • Like 3

Share this post


Link to post
Share on other sites

For a very elegant solution you could change the behaviour of the access control via hooking into the execute function of the ProcessPageView module. You'd either have to modify the behaviour of the checkAccess function (which isn't hookable, but you can define a replacement in your hook) to change the way the redirect url option on the existing templates behaves, or you could add an additional method by hooking into the ProcessTemplates module as well.

I've got an example on one of my boxes, but can't access the files from here - will try and remember tonight.

The usual disclaimer about relying on hooks as a way of changing core behaviour potentially causing issues in future releases applies.

EDIT: The solution becomes elegant when utilising ESRCH's approach in the hook, in addition to modifying the login behaviour accordingly to handle the stored (or not) redirect session variable.

Share this post


Link to post
Share on other sites

@ESRCH

That login code will throw error if you login 3 times with wrong credentials... I already tried to put a note in those various (dozens already and lost track of) threads that use this "exact" frontend login code, which works but has one flaw. Problem is that once the login throttle kicks in you're left with a exception error. It's not obvious and I think posting that code in the forum over and over just creates problems in the long run for everyone copy paste such code. Funny thing is that the code originally is from Ryan himself.

Either Ryan should change the behaviour of the throttle code or you need to use this code instead with a try catch to catch the login throttle error:

if ($user->isLoggedin()) {
    $session->redirect($pages->get('/')->url);
}

if ($input->post->user && $input->post->pass) {
    $username = $sanitizer->username($input->post->user);
    $password = $input->post->pass;
    
    try{
        $u = $session->login($username, $password);
        if ($u) {
            if ($redirectUrl = $session->get('redirect')){
                $session->remove('redirect');
                $session->redirect($redirectUrl);
            } else {
                $session->redirect($pages->get('/')->url);
            }
        } else {
            $error = "Wrong username or password. Login failed.";
        }
    } catch(Exception $e){
       $error = $e->getMessage();
    
    }
}
  • Like 5

Share this post


Link to post
Share on other sites

@Soma

Thanks for the correction, I wasn't aware of this (and I incorrectly changed adrianmak's code). I made an edit in my post so that others might look at your comment.

Share this post


Link to post
Share on other sites

Sorry for perhaps not understanding the above Soma (and others) post, but does anyone know if there is, ideally, a best practice way to have SessionLoginThrottle setup so it redirects to somewhere where a friendly error may be displayed, like the Maintenance Mode module can?

Context: I have a site on PW dev 2.6.17 and when it hit a session throttle problem (me logged in on one computer logging in or out too quickly on a 2nd I think at almost the same time (I wasn't trying to break it—honest)) the result was the generic empty white "Website has encountered an error it has been logged" type message.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By angelo, italy
      Hi guys,
      I've always used WP but I want to swtich to PW. I'm not sure ....
      I'd like to know if it's possible to create a website for an online photo contest.
      The participants of the competition could create their own account, in which they upload their photos. The photos uploaded remain visible only to themselves and the judges.
      From their account they can make the "entrance fee" payment.
      The judges of the competition can create their own account... entering they see the photos of the participants and vote photos
      At the main page I imagine the title of the competition, a button to read the regulation, and a button to register.
      The website should be in Italian and English.
      Thank you!!
       
       
    • By Orkun
      Hi Guys
      How can I make a redirect inside the .htaccess to my custom maintenance.html file when any URL of my Website is accessed except the processwire admin (www.example.com/processwire/).
      Because I want that my User's still can access the website when they are loggedin in Processwire.
      When the current url starts with /processwire or if there is a processwire-login-cookie (Is there a cookie when user is logged in Processwire?) available the redirect should not work. Otherwise it should work.
      How can I achieve this?
    • By Peter Knight
      I have a demo site which I moved to a new VPS for client testing
      We noticed that leaving a page open and then revisiting the site can result in a 25 second(ish) to load time and will then throw a 500 Error.
      The hosting guys had a look and confirmed that the server is fine but the issue could be related to authentication or sessions.
      We are running Page Protector and ProCache so I wondered if there were any known bugs here and any recommended actions.
      My actual PW log doesn't show anything but the server log has plenty of these
       
      2018-12-06 08:14:00 Error xxx.141.1x.101 500 POST /who-we-are/ HTTP/1.0     1.58 K Apache access 2018-12-06 08:14:45 Warning xxx.141.1x.131   mod_fcgid: read data timeout in 45 seconds, referer: http://demo.abc.not/who-we-are/       Apache error 2018-12-06 08:14:45 Error xxx.141.1x.131   End of script output before headers: index.php, referer: http://demo.abc.not/who-we-are/       Apache error 2018-12-06 09:03:18 Error xxx.141.1x.131   2614#0: *667 recv() failed (104: Connection reset by peer) while reading response header from upstream       nginx error Thanks
      P
    • By Marcel
      Hey all,
      I want to customize the mywebsite/processwire/profile page. It's almost all good but I want to get rid of the sections 'Admin Theme' and 'Language' so that the user can just set a new password. (see image)
      Do I have to modify the admin template or how can I do that? Because when I go tree>Admin>Profile there are no fields to add or remove.
      Or where can I find the php file?
      I would appreciate your help.

    • By ridgedale
      Reference: PW 3.0.111 and uikit3 based site using the Regular-Master profile.
      I'm trying to automatically redirect a logged-in user to a custom profile page using $session->redirect() and need to add $user->name to the redirect path.
      All my attempts appear to have failed:
      $session->redirect('/user-profile/')->name; $session->redirect('/user-profile/')->$user->name; $session->redirect('/user-profile/' . get($user->name . '/')); $session->redirect('/user-profile/' & get($user->name)); Can anyone point out where I am going wrong?
×
×
  • Create New...