132

私は、yeoman、grunt、および bower を使用して作成された AngularJS アプリケーションを持っています。

認証をチェックするコントローラーを含むログイン ページがあります。資格情報が正しければ、ホームページにリダイレクトします。

app.js

'use strict';
//Define Routing for app
angular.module('myApp', []).config(['$routeProvider', '$locationProvider',
  function($routeProvider,$locationProvider) {
    $routeProvider
    .when('/login', {
        templateUrl: 'login.html',
        controller: 'LoginController'
    })
    .when('/register', {
        templateUrl: 'register.html',
        controller: 'RegisterController'
      })
    .when('/forgotPassword', {
        templateUrl: 'forgotpassword.html',
        controller: 'forgotController'
      })
   .when('/home', {
       templateUrl: 'views/home.html',
       controller: 'homeController'
    })
    .otherwise({
       redirectTo: '/login'
    });
//    $locationProvider.html5Mode(true); //Remove the '#' from URL.
}]);

angular.module('myApp').factory("page", function($rootScope){
    var page={};
    var user={};
    page.setPage=function(title,bodyClass){
        $rootScope.pageTitle = title;
        $rootScope.bodylayout=bodyClass;
    };
    page.setUser=function(user){
        $rootScope.user=user;
    }
    return page;
});

LoginController.js

'use strict';

angular.module('myApp').controller('LoginController', function($scope, $location, $window,page) {
    page.setPage("Login","login-layout");
    $scope.user = {};
    $scope.loginUser=function()
    {
        var username=$scope.user.name;
        var password=$scope.user.password;
        if(username=="admin" && password=="admin123")
        {
            page.setUser($scope.user);
            $location.path( "/home" );
        }
        else
        {
            $scope.message="Error";
            $scope.messagecolor="alert alert-danger";
        }
    }
});

私が持っているホームページには

<span class="user-info">
    <small>Welcome,</small>
    {{user.name}}
</span>
<span class="logout"><a href="" ng-click="logoutUser()">Logout</a></span>

loginController、ログイン情報を確認し、成功した場合は、サービス ファクトリにユーザー オブジェクトを設定します。これが正しいかどうかはわかりません。

私が必要とするのは、ユーザーがログインすると、ユーザーオブジェクトに値を設定して、他のすべてのページがその値を取得できるようにすることです。

ルートの変更が発生するたびに、コントローラーはユーザーがログインしているかどうかを確認する必要があります。そうでない場合は、ログイン ページに再ルーティングする必要があります。また、ユーザーがすでにログインしてページに戻ってきた場合は、ホームページに移動する必要があります。コントローラーは、すべてのルートの資格情報も確認する必要があります。

ng-cookies について聞いたことがありますが、その使用方法がわかりません。

私が見た例の多くはあまり明確ではなく、ある種のアクセス ロールか何かを使用しています。私はそれをしたくありません。ログインフィルターのみが必要です。誰かが私にいくつかのアイデアを与えることができますか?

4

10 に答える 10

182

私の解決策は 3 つの部分に分けられます: ユーザーの状態はサービスに保存され、ルートが変更されたときに監視する run メソッドで、ユーザーが要求されたページへのアクセスを許可されているかどうかを確認します。ユーザーの状態が変化します。

app.run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) {
    $rootScope.$on('$routeChangeStart', function (event) {

        if (!Auth.isLoggedIn()) {
            console.log('DENY');
            event.preventDefault();
            $location.path('/login');
        }
        else {
            console.log('ALLOW');
            $location.path('/home');
        }
    });
}]);

Authユーザーオブジェクトを処理し、ユーザーがログに記録されているかどうかを知るためのメソッドを持つサービス (名前を付けます) を作成する必要があります。

サービス:

 .factory('Auth', function(){
var user;

return{
    setUser : function(aUser){
        user = aUser;
    },
    isLoggedIn : function(){
        return(user)? user : false;
    }
  }
})

から、イベントapp.runをリッスンする必要があります。$routeChangeStartルートが変更されると、ユーザーがログに記録されているかどうかがチェックされます (isLoggedInメソッドがそれを処理する必要があります)。ユーザーがログインしていない場合は、要求されたルートをロードせず、ユーザーを適切なページにリダイレクトします (あなたの場合はログイン)。

loginControllerログインを処理するには、ログイン ページで を使用する必要があります。Authサービスと対話して、ユーザーをログに記録するかどうかを設定するだけです。

loginController :

.controller('loginCtrl', [ '$scope', 'Auth', function ($scope, Auth) {
  //submit
  $scope.login = function () {
    // Ask to the server, do your job and THEN set the user

    Auth.setUser(user); //Update the state of the user in the app
  };
}])

メインコントローラーから、ユーザーの状態が変化したかどうかをリッスンし、リダイレクトで反応することができます。

.controller('mainCtrl', ['$scope', 'Auth', '$location', function ($scope, Auth, $location) {

  $scope.$watch(Auth.isLoggedIn, function (value, oldValue) {

    if(!value && oldValue) {
      console.log("Disconnect");
      $location.path('/login');
    }

    if(value) {
      console.log("Connect");
      //Do something when the user is connected
    }

  }, true);
于 2014-01-07T12:22:56.087 に答える
21

個々のルートのカスタム動作を定義する最も簡単な方法は、非常に簡単です。

1) :任意のルートにroutes.js新しいプロパティ ( など) を作成しますrequireAuth

angular.module('yourApp').config(function($routeProvider) {
    $routeProvider
        .when('/home', {
            templateUrl: 'templates/home.html',
            requireAuth: true // our custom property
        })
        .when('/login', {
            templateUrl: 'templates/login.html',
        })
        .otherwise({
            redirectTo: '/home'
        });
})

2) 内の要素にバインドされていない最上位のコントローラーでng-view( angular との競合を避けるため)、 にプロパティがある$routeProvider かどうかを確認し、それに応じて動作します。newUrlrequireAuth

 angular.module('YourApp').controller('YourController', function ($scope, $location, session) {
     
     // intercept the route change event
     $scope.$on('$routeChangeStart', function (angularEvent, newUrl) {
         
         // check if the custom property exist
         if (newUrl.requireAuth && !session.user) {
             
             // user isn’t authenticated
             $location.path("/login");
         }
     });
 });
于 2016-07-11T01:23:42.283 に答える
7

Angular でユーザー登録とログイン機能を設定する方法について数か月前に投稿しました。 -ログイン例.aspx

ユーザーがイベントにログインしているかどうかを確認します$locationChangeStart。これがメインの app.js です。

(function () {
    'use strict';
 
    angular
        .module('app', ['ngRoute', 'ngCookies'])
        .config(config)
        .run(run);
 
    config.$inject = ['$routeProvider', '$locationProvider'];
    function config($routeProvider, $locationProvider) {
        $routeProvider
            .when('/', {
                controller: 'HomeController',
                templateUrl: 'home/home.view.html',
                controllerAs: 'vm'
            })
 
            .when('/login', {
                controller: 'LoginController',
                templateUrl: 'login/login.view.html',
                controllerAs: 'vm'
            })
 
            .when('/register', {
                controller: 'RegisterController',
                templateUrl: 'register/register.view.html',
                controllerAs: 'vm'
            })
 
            .otherwise({ redirectTo: '/login' });
    }
 
    run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];
    function run($rootScope, $location, $cookieStore, $http) {
        // keep user logged in after page refresh
        $rootScope.globals = $cookieStore.get('globals') || {};
        if ($rootScope.globals.currentUser) {
            $http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
        }
 
        $rootScope.$on('$locationChangeStart', function (event, next, current) {
            // redirect to login page if not logged in and trying to access a restricted page
            var restrictedPage = $.inArray($location.path(), ['/login', '/register']) === -1;
            var loggedIn = $rootScope.globals.currentUser;
            if (restrictedPage && !loggedIn) {
                $location.path('/login');
            }
        });
    }
 
})();
于 2015-09-02T10:51:09.953 に答える
2

この方法が一番簡単だと思いますが、個人的な好みかもしれません。

ログイン ルート (およびその他の匿名ルート。例: /register、/logout、/refreshToken など) を指定する場合は、次を追加します。

allowAnonymous: true

したがって、次のようなものです。

$stateProvider.state('login', {
    url: '/login',
    allowAnonymous: true, //if you move this, don't forget to update
                          //variable path in the force-page check.
    views: {
        root: {
            templateUrl: "app/auth/login/login.html",
            controller: 'LoginCtrl'
        }
    }
    //Any other config
}

「allowAnonymous: false」を指定する必要はありません。存在しない場合、チェックで false と見なされます。ほとんどの URL が強制的に認証されるアプリでは、これは手間がかかりません。そしてより安全です。新しい URL に追加するのを忘れた場合、起こりうる最悪の事態は、匿名の URL が保護されていることです。逆に「requireAuthentication: true」を指定し、それを URL に追加するのを忘れた場合は、機密性の高いページを公開していることになります。

次に、コード設計に最も適していると思われる場所でこれを実行します。

//I put it right after the main app module config. I.e. This thing:
angular.module('app', [ /* your dependencies*/ ])
       .config(function (/* you injections */) { /* your config */ })

//Make sure there's no ';' ending the previous line. We're chaining. (or just use a variable)
//
//Then force the logon page
.run(function ($rootScope, $state, $location, User /* My custom session obj */) {
    $rootScope.$on('$stateChangeStart', function(event, newState) {
        if (!User.authenticated && newState.allowAnonymous != true) {
            //Don't use: $state.go('login');
            //Apparently you can't set the $state while in a $state event.
            //It doesn't work properly. So we use the other way.
            $location.path("/login");
        }
    });
});
于 2016-12-04T18:58:57.737 に答える
1

app.js

'use strict';
// Declare app level module which depends on filters, and services
var app= angular.module('myApp', ['ngRoute','angularUtils.directives.dirPagination','ngLoadingSpinner']);
app.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'loginCtrl'});
  $routeProvider.when('/home', {templateUrl: 'partials/home.html', controller: 'homeCtrl'});
  $routeProvider.when('/salesnew', {templateUrl: 'partials/salesnew.html', controller: 'salesnewCtrl'});
  $routeProvider.when('/salesview', {templateUrl: 'partials/salesview.html', controller: 'salesviewCtrl'});
  $routeProvider.when('/users', {templateUrl: 'partials/users.html', controller: 'usersCtrl'});
    $routeProvider.when('/forgot', {templateUrl: 'partials/forgot.html', controller: 'forgotCtrl'});


  $routeProvider.otherwise({redirectTo: '/login'});


}]);


app.run(function($rootScope, $location, loginService){
    var routespermission=['/home'];  //route that require login
    var salesnew=['/salesnew'];
    var salesview=['/salesview'];
    var users=['/users'];
    $rootScope.$on('$routeChangeStart', function(){
        if( routespermission.indexOf($location.path()) !=-1
        || salesview.indexOf($location.path()) !=-1
        || salesnew.indexOf($location.path()) !=-1
        || users.indexOf($location.path()) !=-1)
        {
            var connected=loginService.islogged();
            connected.then(function(msg){
                if(!msg.data)
                {
                    $location.path('/login');
                }

            });
        }
    });
});

loginServices.js

'use strict';
app.factory('loginService',function($http, $location, sessionService){
    return{
        login:function(data,scope){
            var $promise=$http.post('data/user.php',data); //send data to user.php
            $promise.then(function(msg){
                var uid=msg.data;
                if(uid){
                    scope.msgtxt='Correct information';
                    sessionService.set('uid',uid);
                    $location.path('/home');
                }          
                else  {
                    scope.msgtxt='incorrect information';
                    $location.path('/login');
                }                  
            });
        },
        logout:function(){
            sessionService.destroy('uid');
            $location.path('/login');
        },
        islogged:function(){
            var $checkSessionServer=$http.post('data/check_session.php');
            return $checkSessionServer;
            /*
            if(sessionService.get('user')) return true;
            else return false;
            */
        }
    }

});

sessionServices.js

'use strict';

app.factory('sessionService', ['$http', function($http){
    return{
        set:function(key,value){
            return sessionStorage.setItem(key,value);
        },
        get:function(key){
            return sessionStorage.getItem(key);
        },
        destroy:function(key){
            $http.post('data/destroy_session.php');
            return sessionStorage.removeItem(key);
        }
    };
}])

loginCtrl.js

'use strict';

app.controller('loginCtrl', ['$scope','loginService', function ($scope,loginService) {
    $scope.msgtxt='';
    $scope.login=function(data){
        loginService.login(data,$scope); //call login service
    };

}]);
于 2016-06-22T06:58:43.087 に答える
0

たとえば、アプリケーションに ap と auc という 2 人のユーザーがいるとします。各ルートに追加のプロパティを渡し、$routeChangeStart で取得したデータに基づいてルーティングを処理しています。

これを試して:

angular.module("app").config(['$routeProvider',
function ($routeProvider) {

    $routeProvider.
            when('/ap', {
                templateUrl: 'template1.html',
                controller: 'template1',
                isAp: 'ap',
            }).
            when('/auc', {
                templateUrl: 'template2.html',
                controller: 'template2',
                isAp: 'common',
            }).
            when('/ic', {
                templateUrl: 'template3.html',
                controller: 'template3',
                isAp: 'auc',
            }).
            when('/mup', {
                templateUrl: 'template4.html',
                controller: 'template4',
                isAp: 'ap',
            }).

            when('/mnu', {
                templateUrl: 'template5.html',
                controller: 'template5',
                isAp: 'common',
            }).                               
            otherwise({
                redirectTo: '/ap',
            });
   }]);

app.js:

.run(['$rootScope', '$location', function ($rootScope, $location) {                
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if (next.$$route.isAp != 'common') {
            if ($rootScope.userTypeGlobal == 1) {
                if (next.$$route.isAp != 'ap') {
                    $location.path("/ap");
                }
            }
            else {
                if (next.$$route.isAp != 'auc') {
                    $location.path("/auc");
                }                        
            }
        }

    });
}]);
于 2016-04-25T05:57:27.680 に答える
0

クライアント側でセッションを心配している理由はすべて、大きな解決策を提案しています。つまり、状態/URL が変更されたときに、tempelate のデータをロードするために ajax 呼び出しを行っていると思います。

Note :- To Save user's data you may use `resolve` feature of `ui-router`.
 Check cookie if it exist load template , if even cookies doesn't exist than 
there is no chance of logged in , simply redirect to login template/page.

これで、任意の API を使用してサーバーから ajax データが返されます。ポイントが登場しました。ユーザーのログイン状態に応じて、サーバーを使用して標準の戻り値の型を返します。これらのリターン コードを確認し、コントローラーでリクエストを処理します。注:- ネイティブに ajax 呼び出しを必要としないコントローラーの場合、このように空の要求をサーバーに呼び出すことができます。server.location/api/checkSession.phpこれはcheckSession.php です。

<?php/ANY_LANGUAGE
session_start();//You may use your language specific function if required
if(isset($_SESSION["logged_in"])){
set_header("200 OK");//this is not right syntax , it is just to hint
}
else{
set_header("-1 NOT LOGGED_IN");//you may set any code but compare that same       
//code on client side to check if user is logged in or not.
}
//thanks.....

他の回答に示されているように、コントローラー内または任意のサービスを介してクライアント側で

    $http.get(dataUrl)
    .success(function (data){
        $scope.templateData = data;
    })
    .error(function (error, status){
        $scope.data.error = { message: error, status: status};
        console.log($scope.data.error.status);
if(status == CODE_CONFIGURED_ON_SERVER_SIDE_FOR_NON_LOGGED_IN){
//redirect to login
  });

注:- 明日または将来、さらに更新します

于 2016-05-09T15:55:02.010 に答える
-1

2 つのメイン サイトでユーザー認証を確認する必要があります。

  • ユーザーが状態を変更すると、'$routeChangeStart'コールバックを使用して確認します
  • インターセプターを使用して、角度から $http リクエストが送信されたとき。
于 2015-03-20T18:27:26.627 に答える