Как сохранить токен носителя аутентификации в файле cookie браузера с помощью AngularJS

Я создал токен носителя, используя ASP.net личность. В 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 :(");
        });
    };

Так Я хочу сохранить этот токен в cookies браузера. Если этот токен присутствует там, то возьмите токен и получите данные с сервера IIS, иначе перенаправьте на страницу входа в систему для входа в систему, чтобы получить новый токен.

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

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

2 ответов


есть $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 :(");
    });
};

Вам также придется добавить угловой модуль cookies код. И добавьте его в свое угловое приложение:angular.module('myApp', ['ngCookies']);. документы для угловых файлов cookie.

я также хотел бы предложить использование 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. Просто измените реализацию с cookies на localStorage.

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

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

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

Я бы передал токен из конечной точки auth в ответе 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'];