2014-11-21 5 views
3

은 그래서 (AngularJS와의 v1.2.26 실행) AngularJS와 내 run이 기능이인증을 확인하고 자동으로 ui-router로 로그인 상태로 리디렉션하는 방법은 무엇입니까?

.run(function(....) { 
    authService.authCheck(); 

    $rootScope.$on('$routeChangeStart', function(event, next, current) { 
     if (next.requireLogin) { 
      if (!authService.isLoggedIn()) { 
       $location.path('/login'); 
       event.preventDefault(); 
      } 
     } 
    }); 

})... 

직접 인증을 예를 들어, 필요한 URL에 액세스 http://127.0.0.1:8080/secret이 함수는 항상 로그인 경로로 리다이렉트되며, 디버깅 후에는 항상 false로 평가됩니다. 기본 페이지에 액세스 할 때 문제없이 실행되는 지정된 경로로 이동합니다.

이의 일부입니다 내 authService

this.authCheck = function() { 
    $http({ 
     method: 'PUT', 
     url: '/api/login' 
    }). 
    success(function(data, status, headers, config) { 
     if (status === 200) { 
      userIsAuthenticated = true; 
     } else { 
      userIsAuthenticated = false; 
     } 
     $rootScope.loginStatus = userIsAuthenticated; 
    }). 
    error(function(data, status, headers, config) { 
     userIsAuthenticated = false; 
     $rootScope.loginStatus = userIsAuthenticated; 
    }); 
}; 

this.isLoggedIn = function() { 
    return userIsAuthenticated; 
}; 

그래서 !authService.isLoggedIn()에 중단 점을 때마다 나는 그것을 실행 블록의 기능은 $rootScope.$on에 도달하기 전에 인증을 시도에도 불구하고 false로 평가되는 것을 볼 수 기능.

정확히 userIsAuthenticated 변수의 상태가 지속적이지 못하게 막습니까?

답변

6

.authCheck 로그인 거기에서 모든 요청을 전송하지 못할 수도 있습니다 실제로 처음 완료 될 때까지 userIsAuthenticated가 true로 설정되지 않음을 의미하는 비동기입니다. 현재 진행중인 경로를 따라 갔다면 수표가 아직 완료되지 않은 상태에서 대기 중으로 전환 한 다음 좀 더 복잡한 코드를 작성해야합니다. 그러나, 그것은 지저분한 차선책입니다.

여기서 가장 좋은 방법은 ui-router이 문제를 해결하도록하는 것입니다. 로그인이 필요한 모든 주에 공통 조상 상태를 만듭니다 (예 : 'session'. 그런 다음 resolve 옵션을 사용하여 인증 확인을 위해 대기 상태의 해결을 기다립니다. 인증되지 않은 경우 특정 상태 전송 거부 오류를 생성합니다.이 오류는 다른 곳에서 잡아서 조치를 취할 수 있습니다 (로그인으로 리디렉션).

.state('session', { 
    resolve: { 
     authentication: ['authService', '$q', function (authService, $q) { 
      return authService.checkAuthentication().then(function() { 
       if (!authService.isAuthenticated) { 
        return $q.reject({ 
         notAuthenticated: true 
        }); 
       } 
      }); 
     }] 
    }, 
    // ... 
}) 
.state('secret', { 
    parent: 'session', 
    // ... 
}); 

다음

$rootScope.$on('$stateChangeError', function (_0, _1, _2, _3, _4, error) { 
    if (error.notAuthenticated) { 
     $state.go('login'); 
    } 
}); 

는 인증 토큰 (세션)에 대한

checkAuthentication: function() { 
    return $http({...}) 
     .success(...) 
     .error(...); 
} 
+0

약속을 사용하지 않고 있지만 호출 ('$ http')은 여전히 ​​비동기 호출로 간주됩니까? 스 니펫에 감사드립니다. 집에있을 때 시도해 보겠습니다. – ymg

+0

'$ http' 호출은 브라우저 잠금을 막기 위해 항상 비동기입니다. 그리고 당신은 약속을 사용합니다 - 반환 값은 특별한 함수'success'와'error'로 확장 된 약속입니다 :) 제 샘플을 사용하려면 모든 것을 반환해야합니다. – hon2a

+0

알겠습니다. 멋진 답변을 주셔서 감사합니다. – ymg

0

응용 프로그램이/secret로부터 요청을 보내도록 허용 했습니까? 가 리디렉션 그래서 당신이 당신의 authService에서

+0

'/ secret' 검사를 (제대로뿐만 아니라 당신의 인증 검사에서 반환해야합니다) 그것이하는 모든 권리입니다. 문제는 내가'/ secret'에 액세스하여 거기에서 유효한 양식을 게시 할 수 있고 서버가 문제가 없다는 것이지만 초기 요청은 내가 말했던 것처럼 문제를 일으키는 것입니다. – ymg

+0

인증이 완료되기 전에 앱이 루트를 변경한다는 것이 문제라는 것을 알고 있습니다! $ routeChangeStart 이벤트를 사용하지 않고이 코드를 사용하여이 문제를 해결할 수 있습니다 (이 기능을 최대한 빨리 완료해야하는 경우 가장 빠른 솔루션입니다) –