Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirection to original URL having hash tag (#) broken in MVC4

I am developing an SPA application using AngularJS working with REST Web API, on top of a very small layer of ASP.NET MVC4. For reasons not important here, I am not using the default Account Controller of MVC4.

basically, I want to share "tasks" between users. My goal is to be able send the URL of a specific "task" entity to any user, via email. Clicking on that URL should launch the authentication. Following a successful authentication, I want to display the real task page info.

AngularJS causes my URLs to have # sign, or a URL of a page displaying the task "XYZ123" is: http://hostname.com/#/tasks/XYZ123

ASP.NET redirects the unauthorized access to that URL to: http://hostname.com/Home/Login?ReturnUrl=%2f#/tasks/XYZ123

This is OK, but the relevant controller method "cuts out" the path from #, so in:

 public ActionResult Login(string returnUrl)

the value of 'returnUrl' will be just "/"

So, I am losing the path: I would like to build a "Connect with Facebook" link having the original URL, like:

http://hostname.com/Login/ExternalLogin?ReturnUrl=%2F#/tasks/XYZ123

but I cannot.

What is the right way to solve this issue?

I can think of creating my own redirection service URL without # tag, but this solution implies additional work, and covers only a case when the system is sending a message with task URL - humans will still try to copy/paste the location URL from the browser.

Thanks for any hint.

Max

like image 264
Max Avatar asked Oct 22 '13 09:10

Max


1 Answers

Yes. A browser cuts '#/tasks/XYZ123' and requests page without that hash. Although the hash itself apears on the logon page - it's the browser's work again. Hash is not traveling to the server.

So when a browser loads the logon page with ?ReturnUrl=%2f#/tasks/XYZ123 we can rewrite Form action and encode the hash.

If the form looks like:

<form action="/Home/Login" method="post" >
    ...
</form>

The javascript code should look like:

<script src="~/js/jquery.js"></script>

<script type="text/javascript">
    $(function() {

        var search = $(location).attr('search') || '';
        var hash = $(location).attr('hash') || '';

        if (hash.length === 0) {                
            if (window.history.pushState) {
                window.history.pushState('login', 'Login', '/Home/Login');
            }
        } else if (search === '?ReturnUrl=%2f') {
            $('form').attr('action', '/Home/Login' + search + encodeURIComponent(hash) );
        }

    });

</script>

The part with window.history.pushState is required for the following:

If there is no hash, then for a SPA its URL (more likely) will be:

http://hostname.com/Home/Login?ReturnUrl=%2f

so here we try to replace URL (without page reload) with more accurate

http://hostname.com/Home/Login
like image 122
Vadim Loboda Avatar answered Oct 21 '22 04:10

Vadim Loboda