web-dev-qa-db-ja.com

AngularJSを使用して認証ベアラートークンをブラウザーCookieに保存する方法

ASP.net Identityを使用してベアラートークンを作成しました。 AngularJSでは、許可されたデータを取得するためにこの関数を作成しました。

$scope.GetAuthorizeData = function () {
  $http({
    method: 'GET',
    url: "/api/Values",
    headers: { 'authorization': 'bearer <myTokenId>' },
  }).success(function (data) {
    alert("Authorized :D");
    $scope.values = data;
  }).error(function () {
    alert("Failed :(");
  });
};

このトークンをブラウザのクッキーに保存したい。このトークンが存在する場合、トークンを取得し、IIS serverからデータを取得します。それ以外の場合は、ログインページにリダイレクトして、新しいトークンを取得します。

同様に、ユーザーがログアウトボタンをクリックすると、ブラウザCookieからトークンが削除されます。

これを行う方法?それは可能ですか?ユーザーを認証および承認する適切な方法ですか?複数のユーザートークンがある場合はどうしますか?

12
Bimal Das

ngCookiesモジュールを使用して、AngularJS APIで利用可能な_$cookies_サービスがあります。以下のように使用できます。

_function controller($cookies) {
    //set cookie
    $cookies.put('token', 'myBearerToken');

    //get cookie
    var token=$cookies.get('token');

    //remove token
    $cookies.remove('token');
}
controller.$inject=['$cookies'];
_

あなたの場合は次のようになります:

_//inject $cookies into controller
$scope.GetAuthorizeData = function () {
    $http({
        method: 'GET',
        url: "/api/Values",
        headers: { 'authorization': 'bearer <myTokenId>' },
    })
    .success(function (data) {
        $cookies.put('token', data);
    }).error(function () {
        alert("Failed :(");
    });
};
_

angular-cookies module コードも追加する必要があります。そして、あなたのangular app:angular.module('myApp', ['ngCookies']);。に追加します。 Docs for Angular Cookies。

また、リクエストごとに手動で設定するのではなく、リクエストごとにベアラヘッダーを設定する_Http interceptor_の使用を提案したいと思います。

_//Create a http interceptor factory
function accessTokenHttpInterceptor($cookies) {
    return {
        //For each request the interceptor will set the bearer token header.
        request: function($config) {
            //Fetch token from cookie
            var token=$cookies.get['token'];

            //set authorization header
            $config.headers['Authorization'] = 'Bearer '+token;
            return $config;
        },
        response: function(response) {
            //if you get a token back in your response you can use 
            //the response interceptor to update the token in the 
            //stored in the cookie
            if (response.config.headers.yourTokenProperty) {
                  //fetch token
                  var token=response.config.headers.yourTokenProperty;

                  //set token
                  $cookies.put('token', token);
            }
            return response;
        }
    };
}
accessTokenHttpInterceptor.$inject=['$cookies'];

//Register the http interceptor to angular config.
function httpInterceptorRegistry($httpProvider) {
    $httpProvider.interceptors.Push('accessTokenHttpInterceptor');
}
httpInterceptorRegistry.$inject=['$httpProvider'];

//Assign to module
angular
    .module('myApp')
    .config(httpInterceptorRegistry)
    .factory('accessTokenHttpInterceptor', accessTokenHttpInterceptor)
_

_http interceptor_を配置すると、各リクエストに_Authorization header_を設定する必要がなくなります。

_function service($http) {
    this.fetchToken=function() {
        //Authorization header will be set before sending request.
        return $http
            .get("/api/some/endpoint")
            .success(function(data) {
                 console.log(data);
                 return data;
            })
    }
}
service.$inject=['$http']
_

ボリスが述べたように、これを解決する方法は他にもあります。 localStorageを使用してトークンを保存することもできます。これは、httpインターセプターでも使用できます。実装をCookieからlocalStorageに変更するだけです。

_function controller($window) {
    //set token
    $window.localStorage['jwt']="myToken";

    //get token
    var token=$window.localStorage['jwt'];
}
controller.$inject=['$window'];
_
15
cbass

データをCookieに保存しないことをお勧めします。セキュリティの目的で、CookieをセキュアおよびHttpOnly(javascriptからアクセス不可)に設定する必要があります。 SSLを使用していない場合は、httpsに移行することをお勧めします。

Json応答で認証エンドポイントからトークンを渡します。

{
    tokenData: 'token'
}

$windowサービスを使用して、トークンデータをsessionStorageに保存できます。

$window.sessionStorage.setItem('userInfo-token', 'tokenData');

ユーザーがページを閉じるとクリアされます。空の文字列に設定することで手動で削除できます。

$window.sessionStorage.setItem('userInfo-token', '');

編集:

Cbassから適応されたデータをキャッチするためのインターセプターの実装(テストされていないため、情報をいじる応答/要求についてオブジェクトを検査できます):

//Create a http interceptor factory
function accessTokenHttpInterceptor($window) {
    return {
        //For each request the interceptor will set the bearer token header.
        request: function($config) {
            //Fetch token from cookie
            var token=$window.sessionStorage.getItem('userInfo-token');

            //set authorization header
            $config.headers['Authorization'] = 'Bearer '+token;
            return $config;
        },
        response: function(response) {
            //if you get a token back in your response you can use 
            //the response interceptor to update the token in the 
            //stored in the cookie
            if (response.config.url === 'api/token' && response.config.data.tokenData) {
                  //fetch token
                  var token=response.config.data.tokenData;

                  //set token
                  $window.sessionStorage.setItem('userInfo-token', token);
            }
            return response;
        }
    };
}

accessTokenHttpInterceptor.$inject=['$window'];
18
Boris