Защищенный заголовок или файл cookie с помощью Angular 1.6 перехватчика

У меня есть этот перехватчик запросов $http

app.config(function($httpProvider) {
  $httpProvider.interceptors.push(function() {
    return {
      request: function(req) {
        // Set the `Authorization` header for every outgoing HTTP request
        req.headers['cdt_app_header'] = 'tamales';
        return req;
      }
    };
  });
});

Можно ли добавить заголовок или файл cookie для каждого запроса $http, но сохранить значение заголовка безопасным/не видимым с помощью JavaScript?

Мы можем добавить слой обфускации с этим заголовком, чтобы предотвратить легкий доступ к нашим конечным точкам API, но я задаюсь вопросом о более надежном решении.

Файлы cookie используются для безопасных сеансов, и они более безопасны, поскольку к ним нельзя получить доступ с помощью JavaScript. Скажем, у нас есть пользователь, который может выполнить этот запрос с интерфейсом:

GET /api/users

мы не хотим, чтобы они могли сделать простой запрос с помощью cURL или браузера без дополнительной информации. Куки файлы, которые мы им даем, дадут им возможность использовать адресную строку браузера, чтобы сделать запрос GET/api/users, но если мы добавим требование о наличии другого cookie или заголовка, то мы можем помешать им получить доступ к конечным точкам которые разрешены, в формате, который мы действительно не хотим использовать.

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

Ответ 1

Я не могу добавить комментарий из-за своего представителя, но что вы делаете в фоновом режиме для авторизации пользователей? Если cookie подписан и содержит разрешения пользователя, не имеет значения, что заголовок отображается на клиенте, поскольку он также будет проверен при обращении к API-интерфейсу.

Ответ 2

в этом примере я использовал HttpRestService для получения RESTful API, прочитайте эту статью

сначала мы создаем сервис для получения наших конфигураций в этом примере getConfigs

мы используем getConfigs в app.run, когда приложение запускается, после получения конфигураций мы устанавливаем их все в header как образец.

после этого мы можем получить userProfile с новым header, а также защитить его, вызвав его из нашего controller, как вы видите.

в этом примере вам нужно определить apiUrl, это ваш URL-адрес хоста api, помните, что после выхода из системы вы можете удалить заголовок, также вы можете динамически определять свои конфигурации, чтобы сделать вашу защиту более безопасной.

HttpRestService.js ссылка github

app.js

var app = angular.module("app", ["HttpRestApp"]);

app.service

app.service("service", ["$http", "$q", "RestService", function (http, q, restService) {
    this.getConfigs = function () {
        var deferred = q.defer();

        http({
            method: "GET",
            async: true,
            headers: {
                "Content-Type": "application/json"
            },
            url: "you url to get configs"
        }).then(function (response) {
            deferred.resolve(response.data);
        }, function (error) {
            deferred.resolve(error);
        });

        return deferred.promise;
    }

    var api = {
        user: "User" //this mean UserController
    }

    //get user with new header
    //this hint to your api with this model "public Get(int id){ return data; }"
    //http://localhost:3000/api/users/123456
    this.getUserProfile= function(params, then) {
        restService.get(params, api.user, true).then(then);
    }
}]);

app.run

app.run(["RestService", "service", function (restService, service) {
   var header = {
      "Content-Type": "application/json"
   }

   //get your configs and set all in the header
   service.getConfigs().then(function (configs) {
      header["systemId"] = configs.systemId;
   });

   var apiUrl = "http://localhost:3000/";

   restService.setBaseUrl(apiUrl, header);
}]);

app.controller

app.controller("ctrl", ["$scope", "service", function ($scope, service) {

    $scope.getUserProfile = function () {
        //this is just sample
        service.getUserProfile({ id: 123456 }, function (data) {
            $scope.user = data;
        });
    }

    $scope.getUserProfile();

}]);