Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>Query-string pattern</h2> <p>Attempting to implement the "navigate back" method described in my question I have decided against using this method because of the limitations I have described above. </p> <p>I have found in practice that a method which works much better is to pass the URL to the page which requires authentication as a query string to the login page, which can then use this to navigate forward to this URL once a user is authenticated.</p> <p>Below is an outline of an implementation of this method which I have adopted. I am still keen to learn about any other login patterns that people have adopted for use in Durandal applications however.</p> <h3>Implementation</h3> <p>In <code>main.js</code> (or anywhere before <code>router.activate()</code> is called) I still guard the route which requires authentication:</p> <pre><code>router.guardRoute = function (instance, instruction) { if (user.isAuthenticated()) { return true; } else { if (instance &amp;&amp; typeof (instance.preventAnonymous) === "boolean") { if (instance.preventAnonymous) { return 'login/' + instruction.fragment; } } return true; } }; </code></pre> <p>In <code>shell.js</code>:</p> <pre><code>return { router: router, activate: function () { router.map([ ... { route: 'login', title: '', moduleId: 'viewmodels/login', nav: true }, { route: 'login/:redirect', title: '', moduleId: 'viewmodels/login', nav: true }, ... ]).buildNavigationModel(); return router.activate(); }, ... } </code></pre> <p>In <code>viewmodels/login.js</code>:</p> <pre><code>viewmodel = { ..., canActivate: function() { if (!user.isAuthenticated()) { return true; } return false; }, activate: function(redirect) { viewmodel.redirect = redirect || ""; }, loginUser() { ... if (user.isAuthenticated()) { router.navigate(viewmodel.redirect); } ... }, ... } </code></pre> <h3>Limitation</h3> <p>One minor negative of this method is the prescense of the page fragment to redirect to upon a succesful login in the application URL query string. If you do not like the prescence of this page fragment in the URL query string, local storage could easily be used instead to store this value. In <code>router.guardRoute</code> one could simple replace the line </p> <pre><code>return 'login/' + instruction.fragment; </code></pre> <p>with</p> <pre><code>/* Check for local storage, cf. http://diveintohtml5.info/storage.html */ if ('localStorage' in window &amp;&amp; window['localStorage'] !== null){ localStorage.setItem("redirect", instruction.fragment); return 'login/'; } else { return 'login/' + instruction.fragment; } </code></pre> <p>and our <code>activate</code> method could look like:</p> <pre><code>activate: function(redirect) { if ('localStorage' in window &amp;&amp; window['localStorage'] !== null){ viewmodel.redirect = localStorage.getItem("redirect"); } else { viewmodel.redirect = redirect || ""; } }, </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload