Serenity: Define page which is automatically loaded after successful login (for current version of Serene)

Created on 21 Mar 2020  路  7Comments  路  Source: serenity-is/Serenity

Hi all,

I would like to configure the page which is automatically loaded after successful login. By default, this is going to "/" which will go to the DashboardController and load the dashboard.

At the moment, I just have changed the return View(...) statement within the DashboardController Index() method to return the desired url - like this:

        public ActionResult Index()
        {
            //return View(MVC.Views.Common.Dashboard.DashboardIndex, new DashboardPageModel());
            return View("~/Modules/Content/Content/ContentIndex.cshtml");
        }

This works, but is there a better way?

With kind regards,

John

Most helpful comment

Hi all and @stixoffire
I think I have figured it out:

within AccountPage.cs, create a new class for the custom Serviceresponse:

    public class LoginServiceResponse  : ServiceResponse
    {
        public string redirectURL { get; set; }
    }

Also within AccountPage.cs, modify the Login ServiceResponse to be like this:

public Result<LoginServiceResponse> Login(LoginRequest request)
        {
            return this.ExecuteMethod(() =>
            {
                request.CheckNotNull();

                if (string.IsNullOrEmpty(request.Username))
                    throw new ArgumentNullException("username");

                var username = request.Username;

                if (WebSecurityHelper.Authenticate(ref username, request.Password, false))
                {
                    var sr = new LoginServiceResponse();
                    sr.redirectURL = "/Content/Content";   // *** Your custom redirect target URL goes here... ***
                    return sr;
                }

                throw new ValidationError("AuthenticationError", Texts.Validation.AuthenticationError);
            });
        }

And within AccountLogin.cshtml, change the LoginButton click function to be like this:

$('#LoginButton').click(function (e) {
    e.preventDefault();
    if (!_this.validateForm()) {
        return;
    }
    var request = _this.getSaveEntity();

    Q.serviceCall({
        url: Q.resolveUrl('~/Account/Login'),
        request: request,
        onSuccess: function (response) {
            var q = Q.parseQueryString();
            var returnUrl = q['returnUrl'] || q['ReturnUrl'];
            if (returnUrl) {

                // *** The standard returnURL querystring parameter is '/' so if it is something else, then you were logged out at some other page and after login again you must be redirected back to that page ***
                if (String(returnUrl) != '/') {

                    var hash = window.location.hash;
                    if (hash != null && hash != '#')
                        returnUrl += hash;
                    window.location.href = returnUrl;
                }
                else {
                    // *** Standard returnURL queryString parameter, redirect to custom url given from server-side ***
                    var redirectURL = response.redirectURL;
                    var hash = window.location.hash;
                    if (hash != null && hash != '#')
                        redirectURL += hash;

                    window.location.href = Q.resolveUrl(redirectURL);
                }

            }
            else {
                // *** in case returnURL is null, redirect to custom url given from server-side ***
                var redirectURL = response.redirectURL;
                var hash = window.location.hash;
                if (hash != null && hash != '#')
                    redirectURL += hash;

                window.location.href = Q.resolveUrl(redirectURL);
            }
        }
    });
});

This should do it.
Hint: As I never have waited until I got logged out at an arbitrary url within the SF app, this is not yet fully tested.

Hope this helps somebody.

With kind regards,

John

All 7 comments

in btn login function from java-script you can do this

$('#LoginButton').click(function (e) {

            e.preventDefault();
            if (!_this.validateForm()) {
                return;
            }
            var request = _this.getSaveEntity();
            Q.serviceCall({
                url: Q.resolveUrl('~/Account/Login'),
                request: request,
                onSuccess: function (response) {
                    var q = Q.parseQueryString();
                    var returnUrl = q['returnUrl'] || q['ReturnUrl'];
                    if (returnUrl) {
                        var hash = window.location.hash;
                        if (hash != null && hash != '#')
                            returnUrl += hash;
                        window.location.href = returnUrl;
                    }
                    else {
                        window.location.href = Q.resolveUrl('~/Dashboard');
                    }
                }
            });
        });

@belalAhmed
How are you passing the URL you want the user to land on ?
Can you show that code ... perhaps this should be a WIKI when it is done .. because I want some people to land on one 'sensitve' page and other users to land on a common page.

As I see it looks like it is in a Query string passed ??

@JohnRanger I love the question - fits something that was in my get around to list..

Hi @belalAhmed ,,
thank you for your feedback. I already looked at the button code - but I don't understand how to set the "returnURL" on the server-side. As @stixoffire already commented - Could you please elaborate how to set returnURL within the action response in the xyzEndpoint.cs?

Many thanks for your help.

With kind regards,

John

Hi all and @stixoffire
I think I have figured it out:

within AccountPage.cs, create a new class for the custom Serviceresponse:

    public class LoginServiceResponse  : ServiceResponse
    {
        public string redirectURL { get; set; }
    }

Also within AccountPage.cs, modify the Login ServiceResponse to be like this:

public Result<LoginServiceResponse> Login(LoginRequest request)
        {
            return this.ExecuteMethod(() =>
            {
                request.CheckNotNull();

                if (string.IsNullOrEmpty(request.Username))
                    throw new ArgumentNullException("username");

                var username = request.Username;

                if (WebSecurityHelper.Authenticate(ref username, request.Password, false))
                {
                    var sr = new LoginServiceResponse();
                    sr.redirectURL = "/Content/Content";   // *** Your custom redirect target URL goes here... ***
                    return sr;
                }

                throw new ValidationError("AuthenticationError", Texts.Validation.AuthenticationError);
            });
        }

And within AccountLogin.cshtml, change the LoginButton click function to be like this:

$('#LoginButton').click(function (e) {
    e.preventDefault();
    if (!_this.validateForm()) {
        return;
    }
    var request = _this.getSaveEntity();

    Q.serviceCall({
        url: Q.resolveUrl('~/Account/Login'),
        request: request,
        onSuccess: function (response) {
            var q = Q.parseQueryString();
            var returnUrl = q['returnUrl'] || q['ReturnUrl'];
            if (returnUrl) {

                // *** The standard returnURL querystring parameter is '/' so if it is something else, then you were logged out at some other page and after login again you must be redirected back to that page ***
                if (String(returnUrl) != '/') {

                    var hash = window.location.hash;
                    if (hash != null && hash != '#')
                        returnUrl += hash;
                    window.location.href = returnUrl;
                }
                else {
                    // *** Standard returnURL queryString parameter, redirect to custom url given from server-side ***
                    var redirectURL = response.redirectURL;
                    var hash = window.location.hash;
                    if (hash != null && hash != '#')
                        redirectURL += hash;

                    window.location.href = Q.resolveUrl(redirectURL);
                }

            }
            else {
                // *** in case returnURL is null, redirect to custom url given from server-side ***
                var redirectURL = response.redirectURL;
                var hash = window.location.hash;
                if (hash != null && hash != '#')
                    redirectURL += hash;

                window.location.href = Q.resolveUrl(redirectURL);
            }
        }
    });
});

This should do it.
Hint: As I never have waited until I got logged out at an arbitrary url within the SF app, this is not yet fully tested.

Hope this helps somebody.

With kind regards,

John

Have quickly put this into the following Wiki article: https://github.com/volkanceylan/Serenity/wiki/Define-page-which-is-automatically-loaded-after-successful-login-dynamically-from-server-side

and will close this issue within a few days.

Regards,

John

Additional info: I found, that this works fine when the project is deployed into the root of the webserver directory. So far I was not able to make this working when the destination of the Serenity project on the webserver where it is being deployed is a subdirectory.

If somebody has a solution which works dynamically both within the visual studio environment and being deployed into a subdirectory of a webserver, please let me know and I will update the wiki.

With kind regards,

John

@JohnRanger just a question for you regarding the path assignments I notice you are using "/"
or "/content/content" Notice AccountLogin has ~/AccountLogin

The difference is one is referring to the site root and the other refers to application application .
So I am thinking, but have not tested ; is the solution is really to supply application root ~ for your redirects .

Rather than type up something nice - here is a nicely typed answer on StackOF.
/ Slash vs ~/ Tilde Slash

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ahsansolution picture ahsansolution  路  3Comments

StefanTheiner picture StefanTheiner  路  3Comments

JohnRanger picture JohnRanger  路  3Comments

chintankukadiya18 picture chintankukadiya18  路  3Comments

Pinellus picture Pinellus  路  3Comments