angularjs, ui-router를 이용한 사용자 인증 처리

angularjs로 개발을 좀 하다보니 ng-router를 확장한 ui-router가 기능이 너무 막강해서 ng-router가 필요 없을 지경에 이르렀다. 이제는 필수 모듈이 된 ui-router가 앵귤러 2.0에 포함될지는 지켜보겠지만 아무튼 오늘은 각설하고 ui-router를 이용한 사용자 인증 처리에 대해 알아보자.

시작하기 앞서, 전체 소스코드는 요기에 있다.

angularjs 라우터 설정하기

일단 라우터를 아래와 같이 설정한다. 밑에 설정에서 눈여겨 볼 것은 admin 페이지에 authenticate라는 값을 추가했다는 점이다. authenticate는 ui-router에서 제공하는 키워드는 아니고 그냥 인증된 사용자만 접근 가능하다라는 의미를 주기 위한 변수에 불과하다. 이제 이 변수의 의미대로 진짜 인증된 사용자만 접근 가능하도록 구현해보자.

  • signin 페이지: 누구나 접근 가능하다.
  • admin 페이지: 인증된 사용자만 접근 가능다.
// routes.js
(function(){
  'use strict';

  angular
    .module('app')
    .config(function ($stateProvider) {
      $stateProvider
        .state('signin', {
          url: '/signin',
          templateUrl: 'signin/signin.html',
          controller: 'SigninCtrl'
        })
        .state('admin', {
          url: '/admin',
          templateUrl: 'app/admin/admin.html',
          controller: 'AdminCtrl',
          authenticate: true
        });
    });

)();

authenticate 값에 따른 라우터 처리

먼저 앵귤러는 .run() 함수에 인자로 넘긴 콜백함수로부터 시작된다. 이 콜백함수는 페이지가 로드되고 필요한 모듈도 모두 로드되면 호출된다. 초기화 과정에 대한 자세한 내용은 다음 기회에…

라우팅은 URL을 변경해 페이지를 이동시키는 것을 이야기하는데 2가지 방법이 있다.

  1. 하나는 서버에서 URL을 해석해 이동(redirect)시키는 방법이고
  2. 또 다른 하나는 ui-router처럼 클라이언트 딴에서 해쉬URL로 이동시키는 방법이다.

여기서 잠깐, HashUrl이란?

hashUrl은 아래와 같이 url에 샵(#)을 붙여 만든 URL을 의미한다.

http://miconblog.com/#somehash

해쉬URL은 문서 안에 있는 ID로 지정된 엘리먼트를 찾아갈때 쓰인다. 보통 최상위 엘리먼트에 <div id='top'> 같은 값을 주고 Top 버튼을 누르면 스르륵~ 맨위로 올라가게 만든 것도 이런 해쉬를 응용한 방법이다. 해쉬의 장점은 문서 안에서 이동하기 때문에 URL이 변경되도 서버를 거치지 않고, 페이지를 변경할수있다는 장점이 있다. 물론 페이지를 변경하려면 hashChanged라는 이벤트를 잘 모니터링하고 있어야한다.

여하튼 다시 돌아와서 ui-router는 URL 상태가 변경되면 $stateChangeStart 라는 이벤트를 발생시켜준다. 이 이벤트는 현재 페이지에서 다른 페이지로 이동하겠다 혹은 이동했다라는 의미이기 때문에 당연히 이벤트의 함께 넘어오는 정보는 이동할 페이지 정보가 되겠다.

// app.js
(function(){
  'use strict';

  angular.module('app', [
    'ui.router'
  ])
  .run(function ($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
      // 이동할 페이지에 authenticate 값이 있는지 확인해서 라우팅한다.
      if( toState.authenticate ){
        $state.transitionTo('signin');
        event.preventDefault();
      }

    });
  });

})();

위 코드처럼 URL의 상태가 변경되면 페이지를 이동하기 전에 authenticate 값을 미리 확인하고 원하는 처리를 할수있다. 위 코드에서는 현재 내가 인증된 상태인지 아닌지 판단하는 코드는 없지만, 만약 넣는다면 아래와 같이 처리할 수 있겠다.

.run(function ($rootScope, $state, User) {

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
      // User 서비스를 추가해서 현재 사용자가 인증된 사용자임을 확인한다.
      if( toState.authenticate && !User.isAuthenticated() ){
        $state.transitionTo('signin');
        event.preventDefault();
      }

    });
  });

정리,

ui-router를 이용한 인증처리를 알아봤는데 다음에는 위 코드에서 사용자 인증에 사용한 User 서비스를 만들어 볼 예정이다.

참고 링크

  • https://medium.com/@mattlanham/authentication-with-angularjs-4e927af3a15f