programing

ui 라우터 onEnter에서 액세스 범위 또는 서비스에 액세스하여 액세스 확인(auth)

itsource 2023. 3. 8. 22:53
반응형

ui 라우터 onEnter에서 액세스 범위 또는 서비스에 액세스하여 액세스 확인(auth)

네, 사용자가 접근을 시도할 때마다 확인해야 하는 URL "/secure page" 상태가 있습니다.사용할 수 있는 onEnter 기능이 있다고 읽었습니다.하지만 스코프나 서비스를 받을 수 없는 것 같습니다.내가 뭘 잘못하고 있지?

        .state('securepage', {
            url: "/securepage",
            template: securepage.html,
            onEnter: function(){
                // if (!$scope.main.isAuthenticated) $state.go("/login");
                // if (!myLoginService.currentUser()) $state.go("/login");

현재 표시되는 옵션은 컨트롤러에서 해결을 사용하거나 인증을 확인하는 것입니다.하지만 인증 체크는 onEnter에 두는 것이 좋지 않을까요?

저도 오늘 비슷한 문제에 부딪혔어요.하루 종일 시간을 들여서, 여기서 이미 제안되고 있는 것 이외의 실행 가능한 해결책을 생각해 냈습니다.

제 주된 목표는 특정 웹 페이지를 선별적으로 보호할 수 있는 쉽고 효과적인 방법을 찾는 것입니다.HTML 또는 관련 컨트롤러를 로드하거나 호출하기 전에 보안 검사를 수행해야 합니다.체크에 실패하면 다른 컨트롤러의 부작용 없이 페이지가 다른 곳으로 전송될 수 있습니다.

나는 다른 제안된 접근법을 시도했다.각각의 문제점은 다음과 같습니다.

  1. OnEnter 사용:

    • 보안 검사를 수행하기 위해 비동기 호출을 발신하는 동안 UI 라우터가 상태 천이를 계속하는 것을 차단할 방법은 없습니다.
  2. $rootScope 사용.$on440$상태Change Start' :

    • rquire 보안 검사를 수행하는 상태의 관리는 $stateProvider.state() 정의에서 분리됩니다.이상적으로는 국가의 정의에 관한 모든 것을 한 곳에서 보는 것이 좋습니다.이것은 쇼스토퍼는 아니지만 이상적이지 않다.
    • 더 큰 문제는 $state가페이지의 초기 로드에 대해 ChangeStart 이벤트가 호출되지 않았습니다.이건 쇼스토퍼야

해결 방법은 해결 함수를 사용하여 뷰 컨트롤러가 호출되기 전에 지연이 완료될 때까지 기다리는 약속을 정의하는 것입니다.이것은 컨트롤러가 비동기식으로 기동하지 않도록 차단하는 데 이상적입니다.

다음은 사용한 코드의 대략적인 개요입니다.

.config(['$stateProvider', function ($stateProvider) {
    // Handler for Restricting Access to a page using the state.resolve call
    var accessRestrictionHandler = function($q, $rootScope, $state) {
            var deferred = $q.defer();

            // make sure user is logged in
            asyncCheckForLogin(function(status) {
                if (status != "Logged In") {
                    // You may save target page URL in cookie for use after login successful later
                    // To get the relative target URL, it is equal to ("#" + this.url).  
                    //      The "this" here is the current scope for the parent state structure of the resolve call.
                    $state.go("loginPage");
                }
                else    // if logged in, continue to load the controllers.  Controllers should not start till resolve() is called.
                    deferred.resolve();
            }.bind(this));

            return deferred.promise;
        };


    $stateProvider
        .state('userProfile', {
            url: '/userProfile',
            views: {
                'main': {
                    templateUrl: 'userProfile.html',
                    controller: 'userProfileCtrl'
                }
            },

            // SIMPLY add the line below to all states that you want to secure
            resolve: { loginRequired : accessRestrictionHandler } 
        })

        .state(.... some other state)
        .state(.... some other state);

}]);

이게 여러분 중 몇 명함에도 도움이 되길 바랍니다.

또 다른 접근법은 서비스/컨트롤러가 "$state"를 듣도록 하는 것입니다.Change Start" 이벤트입니다.여기서, 착신측의 스테이트에 인증이 필요한지 아닌지를 체크해, 요구를 재루팅 할 수 있습니다.다음은 토막입니다.

$rootScope.$on('$stateChangeStart', function (event, nextState, currentState) {
    if (!isAuthenticated(nextState)) {
        console.debug('Could not change route! Not authenticated!');
        $rootScope.$broadcast('$stateChangeError');
        event.preventDefault();
        $state.go('login');
    }
});

isAuthenticated할 수 .체크박스를 켜겠습니다nextState.data인증 관련 속성 등

문제와 이 예를 github 페이지에서 확인하십시오.몇 가지 단서가 될 겁니다

답장이 늦었지만 어쨌든 쓰고 싶다.$root Scope는 가능한 한 건드리지 않는 것이 좋습니다.다음은 제가 현재 작업 중인 코드입니다. 이 코드에서는 귀하의 질문에 대한 또 다른 해결책을 요약합니다.

state('dash', {
                url:'/',
                views:{
                    "topNav":{
                        templateUrl:"user/dash/partials/top-nav.html",
                        controller:'logoutCtrl',
                    },
                    "sideNav":{
                        templateUrl:"user/dash/partials/side-nav.html"
                    },
                    "body":{
                        templateUrl:"user/dash/partials/body.html",
                        controller:'testCtrl'
                    }
                },
                onEnter: function(Auth, $state){
                    if(!AuthSvc.isAuthenticated){
                        $state.go('login');
                    }
                }
            })

ngStorage를 사용하여 JWT를 사용하여 토큰을 로컬 스토리지에 저장하고 있습니다.ngStorage는 onEnter에 삽입한 Auth Factory에 $localStorage 서비스를 제공합니다.

아마 네 말은

.state('securepage', {
        url: "/securepage",
        template: securepage.html,
        //this is how you actually inject things to onEnter property
        onEnter: ['$state','myLoginService',function($state,myLoginService){
             if (!$scope.main.isAuthenticated) $state.go("/login");
             if (!myLoginService.currentUser()) $state.go("/login");`}]
         ....

ui.router 0.2.10에서 angularjs 1.3을 사용하고 있습니다.

이 질문을 받은 이후로 많은 변화가 있었겠지만, 제가 직접 알아내야만 했고, 제 검색을 통해 여기까지 오게 되었기 때문에...

인증 확인만 하면 다음과 같이 할 수 있습니다.

.state('securepage', {
        url: "/securepage",
        template: securepage.html,
        onEnter: function($scope,$state,myLoginService){ //THIS IS THE CHANGE
            if (!$scope.main.isAuthenticated) $state.go("/login");
            if (!myLoginService.currentUser()) $state.go("/login");

provider/service/factory를 onEnter 함수에 거의 많은 것을 넣어 액세스 할 수 있습니다.이 기능은 앱의 .config 내에서 동작합니다.

단, 사용자(ui-router maker)는 커스텀 규칙 함수를 사용하여 .$on('$state') 내에서 처리할 것을 제안합니다.ChangeStart', function(e, to) https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-create-rules-to-prevent-access-to-a-state onEnter가 아닌 왜 이 작업을 하는지 알 수 없습니다.누군가 이 부분에 대해 자세히 설명해 주실 수 있습니다.

언급URL : https://stackoverflow.com/questions/19348917/access-scope-or-service-in-ui-router-onenter-to-check-access-auth

반응형