durandaldurandal-2.0durandal-navigation

How can I have a seperate login page using Durandal that has a different layout then the shell?


I've read through Durandal login page redirect pattern wow, lots of code to do what I'd think would be pretty simple.

I've also read through https://groups.google.com/forum/#!topic/durandaljs/RdGpwIm1oOU as I'd like the login page to have a simple logo with a login form, but I'd also like routing for a registration and about page as well. The rest of my site will have a menu, header, etc which I don't want to show until the user is logged in. Also, I'm not sure how this approach would update when the user logs in.

Another code example that almost does what I want to do: https://github.com/Useful-Software-Solutions-Ltd/Durandal451/blob/master/Durandal451v2/App/global/session.js

So, what should I do? Is there an official way to do this? There seems to be a mish mash of things out there that people have tried. I would think this would be a really common occurrence but couldn't find anything on the main docs.


Solution

  • I'm not sure this is the simplest way, but this is what I got

    you will need to add some extra function after app.start() is triggered.

    main.js

    var auth = require('authentication'); // Authentication module
    
    app.start().then(function()
    {
       // This function will wait for the promise
       auth.init().then(function(data)
       {
          // When successfully authenticate, set the root to shell 
          app.setRoot('views/shell');
       }
    });
    

    authentication.js

    define(function(require)
    {
      var app = require('durandal/app');
    
      return {
         init: function()
         {
            // Initialize authentication...
    
            return system.defer(function(dfd)
            {
                // Check if user is authenticate or if there has stored token
                var isAuthenticate = someOtherFunctiontoCheck();
    
                if (isAuthenticate)
                {
                   dfd.resolve(true); // return promise
                }
                else
                {
                   // When not authenticate, set root to login page
                   app.setRoot('views/login');
                }
            }
         }
      };
    });
    

    good luck! :)

    UPDATE

    login.js

    define(function(require)
    {
       var ko = require('knockout');
       var auth = require('authentication');   
    
       var username = ko.observable();
       var password = ko.observable();
    
       return {
          username: username,
          password: password,
          submitForm: function()
          {
             // Do a login, if success, auth module will take care of it
             // and here will take of the error 
             auth.login(username(), password()).error(function()
             {
                 // notify user about the error (e.g invalid credentials)
             });
          }
       };
    });
    

    Authentication.js

    define(function(require)
    {
      var app = require('durandal/app');
    
      return {
         init: function()
         {
            // Initialize authentication...
    
            return system.defer(function(dfd)
            {
                // Check if user is authenticate or if there has stored token
                var isAuthenticate = someOtherFunctiontoCheck();
    
                if (isAuthenticate)
                {
                   dfd.resolve(true); // return promise
                }
                else
                {
                   // When not authenticate, set root to login page
                   app.setRoot('views/login');
                }
            }
         },
         login: function(username, password)
         {
            // do authenticate for login credentials (e.g for retrieve auth token)
            return $.ajax({
                url  : 'api/login',
                type : 'POST',
                data : {
                   username: username,
                   password: password
                }
            }).then(function(token){
                // on success, stored token and set root to shell
                functionToStoreToken(token);
    
                // Set root to shell
                app.setRoot('views/shell');
            });
         }
      };
    });