[angularjs] 유휴 사용자를 기반으로 Angularjs로 자동 로그 아웃

사용자가 비활성 상태인지 확인하고 angularjs를 사용하여 10 분 동안 비활성 상태가되면 자동으로 로그 아웃 할 수 있습니까?

jQuery를 사용하지 않으려 고했지만 angularjs에서이를 수행하는 방법에 대한 자습서 나 기사를 찾을 수 없습니다. 어떤 도움을 주시면 감사하겠습니다.



답변

Ng-Idle이 상황에서 유용 할 수 있는 모듈을 작성했습니다 . 다음은 지침과 데모가 포함 된 페이지입니다.

기본적으로 사용자 활동 (클릭, 스크롤, 입력과 같은 이벤트)에 의해 중단 될 수있는 유휴 시간 동안 타이머를 시작하는 서비스가 있습니다. 서비스에서 메서드를 호출하여 시간 제한을 수동으로 중단 할 수도 있습니다. 시간 초과가 중단되지 않으면 사용자가 로그 아웃 될 것임을 경고 할 수있는 경고를 카운트 다운합니다. 경고 카운트 다운이 0에 도달 한 후에도 응답하지 않으면 애플리케이션이 응답 할 수있는 이벤트가 브로드 캐스팅됩니다. 귀하의 경우 세션을 종료하고 로그인 페이지로 리디렉션하라는 요청을 보낼 수 있습니다.

또한 일정 간격으로 일부 URL을 ping 할 수있는 연결 유지 서비스가 있습니다. 이것은 사용자가 활성 상태 인 동안 사용자의 세션을 유지하기 위해 앱에서 사용할 수 있습니다. 기본적으로 유휴 서비스는 연결 유지 서비스와 통합되어 유휴 상태가되면 핑을 일시 중단하고 돌아 오면 다시 시작합니다.

시작하는 데 필요한 모든 정보 는 위키의 자세한 내용과 함께 사이트 에 있습니다 . 그러나 다음은 시간 초과시 로그 아웃하는 방법을 보여주는 구성 스 니펫입니다.

angular.module('demo', ['ngIdle'])
// omitted for brevity
.config(function(IdleProvider, KeepaliveProvider) {
  IdleProvider.idle(10*60); // 10 minutes idle
  IdleProvider.timeout(30); // after 30 seconds idle, time the user out
  KeepaliveProvider.interval(5*60); // 5 minute keep-alive ping
})
.run(function($rootScope) {
    $rootScope.$on('IdleTimeout', function() {
        // end their session and redirect to login
    });
});


답변

사용중인 데모 보기 angularjs및 브라우저 로그보기

<!DOCTYPE html>
<html ng-app="Application_TimeOut">
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
</head>

<body>
</body>

<script>

var app = angular.module('Application_TimeOut', []);
app.run(function($rootScope, $timeout, $document) {
    console.log('starting run');

    // Timeout timer value
    var TimeOutTimerValue = 5000;

    // Start a timeout
    var TimeOut_Thread = $timeout(function(){ LogoutByTimer() } , TimeOutTimerValue);
    var bodyElement = angular.element($document);

    /// Keyboard Events
    bodyElement.bind('keydown', function (e) { TimeOut_Resetter(e) });
    bodyElement.bind('keyup', function (e) { TimeOut_Resetter(e) });

    /// Mouse Events    
    bodyElement.bind('click', function (e) { TimeOut_Resetter(e) });
    bodyElement.bind('mousemove', function (e) { TimeOut_Resetter(e) });
    bodyElement.bind('DOMMouseScroll', function (e) { TimeOut_Resetter(e) });
    bodyElement.bind('mousewheel', function (e) { TimeOut_Resetter(e) });
    bodyElement.bind('mousedown', function (e) { TimeOut_Resetter(e) });

    /// Touch Events
    bodyElement.bind('touchstart', function (e) { TimeOut_Resetter(e) });
    bodyElement.bind('touchmove', function (e) { TimeOut_Resetter(e) });

    /// Common Events
    bodyElement.bind('scroll', function (e) { TimeOut_Resetter(e) });
    bodyElement.bind('focus', function (e) { TimeOut_Resetter(e) });

    function LogoutByTimer()
    {
        console.log('Logout');

        ///////////////////////////////////////////////////
        /// redirect to another page(eg. Login.html) here
        ///////////////////////////////////////////////////
    }

    function TimeOut_Resetter(e)
    {
        console.log('' + e);

        /// Stop the pending timeout
        $timeout.cancel(TimeOut_Thread);

        /// Reset the timeout
        TimeOut_Thread = $timeout(function(){ LogoutByTimer() } , TimeOutTimerValue);
    }

})
</script>

</html>

아래 코드는 순수한 자바 스크립트 버전입니다.

<html>
    <head>
        <script type="text/javascript">
            function logout(){
                console.log('Logout');
            }

            function onInactive(millisecond, callback){
                var wait = setTimeout(callback, millisecond);
                document.onmousemove =
                document.mousedown =
                document.mouseup =
                document.onkeydown =
                document.onkeyup =
                document.focus = function(){
                    clearTimeout(wait);
                    wait = setTimeout(callback, millisecond);
                };
            }
        </script>
    </head>
    <body onload="onInactive(5000, logout);"></body>
</html>

최신 정보

@Tom 제안으로 솔루션을 업데이트했습니다.

<!DOCTYPE html>
<html ng-app="Application_TimeOut">
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
</head>

<body>
</body>

<script>
var app = angular.module('Application_TimeOut', []);
app.run(function($rootScope, $timeout, $document) {
    console.log('starting run');

    // Timeout timer value
    var TimeOutTimerValue = 5000;

    // Start a timeout
    var TimeOut_Thread = $timeout(function(){ LogoutByTimer() } , TimeOutTimerValue);
    var bodyElement = angular.element($document);

    angular.forEach(['keydown', 'keyup', 'click', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mousedown', 'touchstart', 'touchmove', 'scroll', 'focus'],
    function(EventName) {
         bodyElement.bind(EventName, function (e) { TimeOut_Resetter(e) });
    });

    function LogoutByTimer(){
        console.log('Logout');
        ///////////////////////////////////////////////////
        /// redirect to another page(eg. Login.html) here
        ///////////////////////////////////////////////////
    }

    function TimeOut_Resetter(e){
        console.log(' ' + e);

        /// Stop the pending timeout
        $timeout.cancel(TimeOut_Thread);

        /// Reset the timeout
        TimeOut_Thread = $timeout(function(){ LogoutByTimer() } , TimeOutTimerValue);
    }

})
</script>
</html>

Plunker에서 업데이트 된 버전을 보려면 여기를 클릭하십시오.


답변

이를 수행하는 방법은 여러 가지가 있어야하며 각 접근 방식은 특정 애플리케이션에 더 잘 맞아야합니다. 대부분의 앱에서는 단순히 키 또는 마우스 이벤트를 처리하고 로그 아웃 타이머를 적절하게 활성화 / 비활성화 할 수 있습니다. 즉, 내 머리 위에 “멋진”AngularJS-y 솔루션이 다이제스트 루프를 모니터링하고 있는데, 마지막 [지정된 기간] 동안 아무 것도 트리거되지 않은 경우 로그 아웃됩니다. 이 같은.

app.run(function($rootScope) {
  var lastDigestRun = new Date();
  $rootScope.$watch(function detectIdle() {
    var now = new Date();
    if (now - lastDigestRun > 10*60*60) {
       // logout here, like delete cookie, navigate to login ...
    }
    lastDigestRun = now;
  });
});


답변

Boo의 접근 방식을 사용했지만 사용자가 다른 다이제스트가 실행 된 후에 만 ​​시작되었다는 사실이 마음에 들지 않습니다. 즉, 사용자가 페이지 내에서 작업을 시도한 다음 즉시 시작될 때까지 로그인 상태를 유지한다는 의미입니다.

마지막 작업 시간이 30 분 이상 전인지 확인하는 간격을 사용하여 강제로 로그 오프하려고합니다. $ routeChangeStart에 연결했지만 Boo의 예에서와 같이 $ rootScope. $ watch에 연결할 수도 있습니다.

app.run(function($rootScope, $location, $interval) {

    var lastDigestRun = Date.now();
    var idleCheck = $interval(function() {
        var now = Date.now();
        if (now - lastDigestRun > 30*60*1000) {
           // logout
        }
    }, 60*1000);

    $rootScope.$on('$routeChangeStart', function(evt) {
        lastDigestRun = Date.now();
    });
});


답변

angular-activity-monitor여러 공급자를 주입하는 것보다 더 간단한 방법으로 사용할 수도 있으며 , 다이제스트 루프를 수동으로 트리거하는 것을 방지하기 위해 setInterval()(vs. angular ‘s $interval)를 사용 합니다 (이는 의도하지 않게 항목을 유지하는 것을 방지하는 데 중요합니다).

궁극적으로 사용자가 비활성 상태이거나 가까워지는시기를 결정하는 몇 가지 이벤트 만 구독하면됩니다. 따라서 10 분 동안 활동이없는 사용자를 로그 아웃하려면 다음 스 니펫을 사용할 수 있습니다.

angular.module('myModule', ['ActivityMonitor']);

MyController.$inject = ['ActivityMonitor'];
function MyController(ActivityMonitor) {
  // how long (in seconds) until user is considered inactive
  ActivityMonitor.options.inactive = 600;

  ActivityMonitor.on('inactive', function() {
    // user is considered inactive, logout etc.
  });

  ActivityMonitor.on('keepAlive', function() {
    // items to keep alive in the background while user is active
  });

  ActivityMonitor.on('warning', function() {
    // alert user when they're nearing inactivity
  });
}


답변

나는 Buu의 접근 방식을 시도했지만 $ interval 및 $ timeout 함수 실행을 포함하여 다이 제스터를 실행하도록 트리거하는 이벤트의 수가 너무 많기 때문에 제대로 얻을 수 없었습니다. 이렇게하면 사용자 입력에 관계없이 응용 프로그램이 유휴 상태가되지 않는 상태가됩니다.

실제로 사용자 유휴 시간을 추적해야하는 경우 좋은 각도 접근 방식이 있는지 확실하지 않습니다. https://github.com/witoldsz/angular-http-auth 여기에 Witoldz가 더 나은 접근 방식을 표시한다고 제안합니다 . 이 접근 방식은 자격 증명이 필요한 작업을 수행 할 때 사용자에게 재 인증하라는 메시지를 표시합니다. 사용자가 인증되면 이전에 실패한 요청이 다시 처리되고 아무 일도 일어나지 않은 것처럼 응용 프로그램이 계속됩니다.

이는 사용자의 인증이 만료 되더라도 여전히 애플리케이션 상태를 유지할 수 있고 작업을 잃지 않을 수 있기 때문에 사용자가 활성 상태 인 동안 사용자의 세션이 만료 될 수 있다는 우려를 처리합니다.

클라이언트에 일종의 세션 (쿠키, 토큰 등)이있는 경우 해당 세션도보고 만료되면 로그 아웃 프로세스를 트리거 할 수 있습니다.

app.run(['$interval', function($interval) {
  $interval(function() {
    if (/* session still exists */) {
    } else {
      // log out of client
    }
  }, 1000);
}]);

업데이트 : 여기에 우려를 보여주는 플렁크가 있습니다. http://plnkr.co/edit/ELotD8W8VAeQfbYFin1W . 이것이 증명하는 것은 다이 제스터 실행 시간이 간격이 틱할 때만 업데이트된다는 것입니다. 간격이 최대 개수에 도달하면 소화기가 더 이상 실행되지 않습니다.


답변

ng-Idle은 갈 길처럼 보이지만 Brian F의 수정 사항을 파악할 수 없었고 수면 세션에도 시간 초과를 원했고 매우 간단한 사용 사례를 염두에 두었습니다. 나는 그것을 아래 코드로 줄였습니다. 이벤트를 연결하여 시간 초과 플래그를 재설정합니다 ($ rootScope에 느리게 배치됨). 사용자가 반환하고 이벤트를 트리거 할 때만 시간 초과가 발생했음을 감지하지만 그 정도면 충분합니다. angular의 $ location을 여기서 작업 할 수는 없지만 document.location.href를 사용하면 작업이 완료됩니다.

.config가 실행 된 후 내 app.js에 이것을 붙였습니다.

app.run(function($rootScope,$document)
{
  var d = new Date();
  var n = d.getTime();  //n in ms

    $rootScope.idleEndTime = n+(20*60*1000); //set end time to 20 min from now
    $document.find('body').on('mousemove keydown DOMMouseScroll mousewheel mousedown touchstart', checkAndResetIdle); //monitor events

    function checkAndResetIdle() //user did something
    {
      var d = new Date();
      var n = d.getTime();  //n in ms

        if (n>$rootScope.idleEndTime)
        {
            $document.find('body').off('mousemove keydown DOMMouseScroll mousewheel mousedown touchstart'); //un-monitor events

            //$location.search('IntendedURL',$location.absUrl()).path('/login'); //terminate by sending to login page
            document.location.href = 'https://whatever.com/myapp/#/login';
            alert('Session ended due to inactivity');
        }
        else
        {
            $rootScope.idleEndTime = n+(20*60*1000); //reset end time
        }
    }
});