3

My team is going to build a single-page-application for our future project. At the moment, I have a problem with designing the app with login page. There are 2 approaches:

  1. Create the login page as a separate page, the rest of the app is another single page.
  2. The app has only 1 page and the login page will be a view in the app which is switched back and forth using javascript.

I don't know which approach I should take. I have read some discussions on the internet, it seems like it's more popular to create the login page as a separate page, the reason for this is we can use normal cookie-based authentication with session on server, redirect users to default page (main page) after successful login, and so on. Therefore, I'm thinking about creating the login page as a separate page, but I have a problem with deep linking.

For example, let's say I have 2 pages: login.html, index.html (main page). When an unauthenticated user requests a page like this index.html#product=1, the user will be redirected to the login.html, after successfully loging in, redirect the user back to index.html#product=1. But at this point, the #product=1 is lost.

Please advice me on how to keep the deep link or should I take the second approach? Thank you

Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • what language will the application be built in? – acutesoftware Jun 28 '13 at 08:36
  • @acutesoftware: planning to use angularjs and asp.net mvc4, web api. But I think the language does not matter. – Khanh TO Jun 28 '13 at 08:39
  • I want to go with approach 1, can you guide me? – NgaNguyenDuy Dec 28 '15 at 08:03
  • @NgaNguyenDuy: As I said in the question, there are problems associated with approach 1, we should go with approach 2 as I said in the answer. – Khanh TO Dec 29 '15 at 09:26
  • @KhanhTO: Yes, I also want to follow the second approach but i have trouble with ng-view for login page and main page. The GUI for login page is completely difference with main page then i can't use same ng-view for them. – NgaNguyenDuy Dec 30 '15 at 14:13
  • @NgaNguyenDuy: You could create a top level `ng-view` (e.x on `` tag), this ng-view could hold your login or your main page which contains another ng-view. If this does not answer your question, please ask another question on SO with more code example so that people can help you easier. – Khanh TO Dec 31 '15 at 02:03
  • @KhanhTO: Thank for you solution. Will try now. :) – NgaNguyenDuy Dec 31 '15 at 02:11
  • @NgaNguyenDuy: I recommend using ui-router instead: https://github.com/angular-ui/ui-router . See my answer below with an example. – Khanh TO Dec 31 '15 at 03:21

2 Answers2

0

If you are building a single page app, it would be 'nicer' from the users point of view to have it all on one page, so I would suggest option 2.

Not sure if you need javascript to switch it though - you could use something like the following (PHP code)

At the start of the application saves what view the user is looking at and checks if the user pressed 'submit' on the login form

 $selected_menu = $_GET['menu'] ;

 //check to see if they've submitted the login form  
 if(isset($_POST['submit-login'])) {  

If the login is successful, redirect them back to the same page with the appropriate view as a parameter

Then in the main page of the app when you are about to display data you would check to see if the user is validated, and if not then present the login form as part of the page.

 $usr = CheckLogon(); 
 if ( $usr == "" ) {  // check for correct test to make sure user is logged on
     ShowLoginForm(); 
     ....
acutesoftware
  • 1,091
  • 3
  • 14
  • 33
  • 1
    Thanks for the answer, but this is similar to creating the login page as a separate page. You're using full-page refresh and redirects. – Khanh TO Jun 28 '13 at 09:19
  • Very good point - brain fade on my part. I would still go with your 2nd option though and as you say, use javascript to catch the user login prompt and refresh the appropriate page. – acutesoftware Jun 28 '13 at 09:35
0

I decided to go with approach 2: The app has only 1 page and the login page will be a view in the app which is switched back and forth using javascript.. I found out that it's not difficult to do and I can still use normal cookie-based authentication with session on server, redirect users to default page (main page) after successful login, and so on. Here is a sample code how I do it with angularjs.

Routing:

var App = angular.module('App', ["ui.state"]);

App.config(function ($stateProvider, $routeProvider) {
   $stateProvider.
   .state('login', {
        url: "/login?returnUrl",
        templateUrl: '/Home/Login',
        controller:"LoginController"
    })
    .state('main', {
        url: "/main",
        abstract:true,
        templateUrl: '/Home/Main',
        controller: "MainController"
     })
})
.run(function ($rootScope, $state, $stateParams, $location) {
     $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error){ 
        if (error.status == 401) {
            $state.transitionTo("login", { returnUrl: $location.url() });
        }
     })
});

The point here is when there is a route change error with status 401 (from the server) indicating that the user is not logged in, I will transition to login state with the return url.

After the user successfully logging in using ajax, I will transition the state back to my main view. Something like this:

$http.post("/Login", JSON.stringify({UserName:username,Password:password}))
     .success(function (data, status, headers, config) {
        var returnUrl = $stateParams.returnUrl ? $stateParams.returnUrl : "mydefaulturl";
        $location.url(returnUrl);
 })

With this approach, now I'm able to create deep-link to jump to a specific state in my app with login page and return url.

Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • I have written a blog post about this that may interest you http://jonsamwell.com/url-route-authorization-and-security-in-angular/ – Jon Jul 06 '14 at 13:59