2015-12-31 1 views
9

Я создал токен-носитель, используя идентификатор ASP.net. В AngularJS я написал эту функцию для получения разрешенных данных.Как хранить токен на предъявителя в браузере cookie с помощью 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. В противном случае перейдите на страницу входа в систему, чтобы войти, чтобы получить новый токен.

Аналогичным образом, если пользователь нажимает кнопку выхода, он должен удалить маркер из cookie браузера.

Как это сделать? Это возможно? Правильный ли способ аутентификации и авторизации пользователя? Что делать, если есть несколько токенов пользователей?

ответ

11

Существует доступно $cookies обслуживания в API AngularJS с использованием модуля ngCookies. Он может быть использован, как показано ниже:

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.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']; 
+0

Я. Готов. Спасибо. Хорошее объяснение. –

+0

Привет, где будет '' be? где его найти? – Kavipriya

14

Я бы посоветовал не хранить данные в файле cookie, в целях безопасности вы должны установить файлы cookie для защиты и HttpOnly (недоступны из javascript). Если вы не используете SSL, я бы предложил перейти на https.

Я бы передать маркер от Идентой конечной точки в ответ JSon:

{ 
    tokenData: 'token' 
} 

Вы можете сохранить данные маркеров в sessionStorage с помощью $window услуги:

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

Это будет очищено как только пользователь закроет страницу, и вы можете вручную удалить ее, установив ее в пустую строку:

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

Edit:

реализации перехватчика для отлова данных, адаптированных из 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']; 
+0

Большое спасибо. Я еще не пробовал $ window в угловом JS. Никакой идеи использовать SSL. Где я должен писать эти коды? Можете ли вы дать мне более четкий ответ. –

+0

Вы можете поместить обработчики для хранения сеанса в службу или как cbass упоминает ниже, используя httpInterceptor. – Boris

+2

Сохранение маркера в хранилище сеансов означает также, что если я открою ссылку на новой вкладке, токен из хранилища сеансов недоступен. Пользователь должен будет снова аутентифицироваться (на каждой вкладке), что действительно раздражает. Возможное решение: http://stackoverflow.com/a/32766809/1878249 – goflo