SSbits - Home page
Site by Carbon Crayon
Submit a Post >

Snippets - Little bits of code to make you happy

Set the Redirect after a successful Member Login

The Member system that comes with SilverStripe offers substantial control over your site's authentication capabilities. It often requires the developer to build out or extend most common functionality to websites. This is great in that you are never "stuck" with the out-of-the-box offerings, but as any SS dev knows you end up with a little bag of Member tricks that gets used across many projects. Presented here is one that I use often.

Update 01/01/2010: Astute Commenter Rick noted that there is a far easier way to accomplish this using Security::set_default_login_dest('urlsegment');  The below snippet is best used for extending the login process for more complex scenarios.

When a Member logs in to /Security/login without a ?BackURL= specified, they are always redirected back to the form with a success message and form without any fields. While this works great to keep the code/form tight, it is a less than ideal use experience. Modifying this behavior is a little tricky as much of the controller and rendering actions are fixed in the Security class. This is further complicated by the use of Director::redirect calls that set response headers when the login form is processed. I find by overriding the form and replacing it with the excellent useCustomClass call works well.

The Problem: Base /Security/login form redirects to itself on success, always tagging ?BackURL=/home looks sort of messy across your site.

The Solution: Make the base MemberLoginForm redirect somewhere useful on success.

We begin by extending the MemberLoginForm and the method that does all the dirty work; dologin(). Create the file GoHomeLoginForm.php and add the following code:

 

<?php
/**
 * Overriding the base login form to redirect somewhere useful,
 * in this case to the site index
 */
class GoHomeLoginForm extends MemberLoginForm {
	public function dologin($data) {
		parent::dologin($data);
		if( Director::redirected_to() and Member::currentUserID() ) {
			$this->controller->response->removeHeader('Location');
			Director::redirect(Director::baseURL());
		}
	}
}

Now we need to override the MemberLoginForm with our GoHomeLoginForm in our _config.php:

 

/*	Always redirect somewhere meaningful */
Object::useCustomClass('MemberLoginForm', 'GoHomeLoginForm');

Now do a /dev/build/flush=all and you're gold.

Testing for a redirect being set and a current member set in the session ensures that only users who have successfully logged in will get our custom destination. You can override with any destination you please, such as a '/myaccount/' section or even plain old '/'.

This has been tested on SS 2.3 and 2.4 using the default Member Authenticator.

  • Rick Harvey
    03/01/2011 8:54am (4 years ago)

    Enjoyed your Snippet!

    Perhaps a simpler way (to set a site wide redirect after login) is to set the default login destination (e.g. in _config.php):
    Security::set_default_login_dest('urlsegment');

    Though I always try to return to the calling page (after login) by setting a redirect in the login link (e.g. in the page template):
    <a href="Security/login?BackURL=/$URLSegment/" title="Login">Login</a>

  • dalesaurus
    03/01/2011 6:51pm (4 years ago)

    Ahh, very interesting! I had never noticed that feature before even though SVN says that Sam added it 2+ years ago: http://open.silverstripe.org/changeset/62653

    That is certainly an easier way to direct to an URL segment after login. I suppose you'd only need my snippet above if you had custom logic you'd like to introduce. Thanks Rick, nice catch!

    Note that setting Security::set_default_login_dest() will always be overridden by the presence of a BackURL=xxxxx URL parameter.

  • Tim
    23/08/2012 3:44am (2 years ago)

    A little bit late on this one , but an easy (albeit very hacky) way of doing it is if you add this to a js file that is called on every page:

    $('input[name=BackURL]').each(function(){
    $(this).val('WHATEVERURLYOUWANT');
    });
    (obviously requires jQuery, but i'm sure it can be re-written for vanilla javascript)

    this means you don't have to have a seperate template file for your login and is essentially *global*

  • zoao
    08/12/2012 9:22pm (2 years ago)

    Very good tutorial.
    In my case I need redirect the user after login, according to their permissions. If is administrator goes to CMS admin, if is a student goes to the student profile.
    I made small modifications in the code to silverstripe 3.0.3:

    public function dologin($data) {
    parent::dologin($data);
    if( $this->controller->redirectedTo() and Member::currentUserID() ) {
    $member = Member::currentUser();

    if(Permission::checkMember($member, "STUDENT_ACCESS"))
    {
    $this->controller->response->removeHeader('Location');
    $this->controller->redirect(SiteTree::get_by_link('student')->Link());
    }
    else if(Permission::checkMember($member, "CMS_ACCESS_LeftAndMain"))
    {
    $this->controller->response->removeHeader('Location');
    $this->controller->redirect(singleton('CMSMain')->Link());
    }
    }
    }

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image njorndare
6 article image Ty Barho
7 article image Martijn van Nieuwenhoven
8 article image Darren-Lee
9 article image Roman Schmid
10 article image Matt Clegg

View full leaderboard


Advertisement