2016-07-06 7 views
2

私は角度アプリの認証モジュールを作るのにthis blogのコードを使用しています。認証:許可するページを更新するように強制しました

私は、ログインフォーム、送信ボタン、および制限されたルートを照会する「プロファイル」ボタンを含むテストページを持っています。

const authenticate = expressJwt({ 
    secret: SECRET 
}); 
app.get('/me', authenticate, function(req, res) { 
    res.status(200).json(req.user); 
}); 

ログインが正常に動作します:

<div class="container-fluid" ng-controller="AuthCtrl as auth"> 
    <input type="text" ng-model="auth.user.username"> 
    <input type="text" ng-model="auth.user.password"> 
    <button ng-click="auth.login(auth.user)">LOGIN</button> 
    <button ng-click="auth.profile()">PROFILE</button> 
</div> 

私は、ログイン後に照会しています制限ルートは、次のように定義されます。私はsessionStorageに入れたトークンを受け取ります。 プロファイルボタンをクリックすると(私にリクエストする)、不正なエラーが発生します。

ページを更新してもう一度プロフィールをクリックすると、わかりやすい動作が得られます。 (/ meはエラーなしでユーザーデータを返します)

その後トークンを手動で削除すると、ページを更新するまで/ meにアクセスできます。

これは私のサービスである:

function loginService($http) { 
    this.login = function(user) { 
     return $http.post('/auth', user).then(
      function(response) { 
       return response.data; 
      }, 
      function(response) { 
       return response; 
      }); 
    }; 
    this.profile = function() { 
     return $http.get('/me').then(
      function(response) { 
       return response.data; 
      }, 
      function(response) { 
       return response; 
      }); 
    }; 
} 

angular 
    .module('app') 
    .service('loginService', loginService); 

そして、これはhttpProviderと私のコントローラです:

function AuthCtrl($window, $http, loginService) { 
    this.user = {username: "", password: ""}; 
    this.login = function(user) { 
     loginService.login(user).then(function(data) { 
      $window.sessionStorage.token = data.token; 
     }); 
    }; 
    this.profile = function() { 
     loginService.profile().then(function(data) { 
      console.log(data); 
     }); 
    }; 
} 

function config($httpProvider, $windowProvider) { 
    var window = $windowProvider.$get(); 
    if(window.sessionStorage.token) { 
     var token = window.sessionStorage.token; 
     $httpProvider.defaults.headers.common.Authorization = 'Bearer ' + token; 
    } 
}; 

angular 
    .module('app') 
    .config(config) 
    .controller('AuthCtrl', AuthCtrl); 

問題はのsessionStorageにトークンを格納またはHTTPプロバイダから来てもらえますか?

最終的にsecure cookie methodを実装しますが、これを解決する前にこの問題を解決しておきたいと思います。

答えて

1

最後に、コードが$httpProviderになるとわかりました。

function config($httpProvider, $windowProvider) { 
    var window = $windowProvider.$get(); 
    if(window.sessionStorage.token) { 
     var token = window.sessionStorage.token; 
     $httpProvider.defaults.headers.common.Authorization = 'Bearer ' + token; 
    } 
}; 

プロバイダオプションは、アプリケーションの読み込み中に1回だけ設定されます。 ページをリロードすると、設定コードが再実行され、予期したとおりにif(window.sessionStorage.token)の状態が入力されます。

この設定を動的にするには、私はそうのようinterceptor(工場)を作成する必要がありました:

function config($httpProvider) { 
    $httpProvider.interceptors.push('authInterceptor'); 
}; 

function authInterceptor($rootScope, $q, $window) { 
    return { 
     request: function (config) { 
      config.headers = config.headers || {}; 
      if ($window.sessionStorage.token) { 
       config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token; 
      } 
      return config; 
     }, 
     responseError: function (rejection) { 
      if (rejection.status === 401) { 
       console.log("not authorised"); 
      } 
      return $q.reject(rejection); 
     } 
    }; 
}; 

angular 
    .module('app') 
    .config(config) 
    .controller('AuthCtrl', AuthCtrl) 
    .factory('authInterceptor', authInterceptor); 
関連する問題