Подтвердить что ты не робот

Маршрутизация и токен аутентификации AngularJS с webapi

Я хочу создать пример аутентификации и авторизации в приложении SPA angularjs, используя asp.net mvc webapi в качестве бэкэнд-сервера и клиентской маршрутизации (без cshtml). Ниже приведен только пример функций, которые можно использовать для создания полного примера. Но я просто не могу все это сказать. Любая помощь была оценена.

Вопросы:

  • Что лучше всего: Cookie или Token?
  • Как создать токен-носитель в angular для авторизации по каждому запросу?
  • Проверка функций API?
  • Как сохранить аутентификацию, подписанную пользователем на клиенте?

Пример кода:

  • Вход в систему

    <form name="form" novalidate>
     <input type="text" ng-model="user.userName" />
     <input type="password" ng-model="user.password" />
     <input type="submit" value="Sign In" data-ng-click="signin(user)">
    </form>
    
  • Аутентификация angular Контроллер

    $scope.signin = function (user) {
    $http.post(uri + 'account/signin', user)
        .success(function (data, status, headers, config) {
            user.authenticated = true;
            $rootScope.user = user;
            $location.path('/');
        })
        .error(function (data, status, headers, config) {
    
            alert(JSON.stringify(data));
            user.authenticated = false;
            $rootScope.user = {};
        });
    };
    
  • Код API моей API-интерфейса.

    [HttpPost]
    public HttpResponseMessage SignIn(UserDataModel user)
    {
        //FormsAuthetication is just an example. Can I use OWIN Context to create a session and cookies or should I just use tokens for authentication on each request? How do I preserve the autentication signed in user on the client?
        if (this.ModelState.IsValid)
        {
            if (true) //perform authentication against db etc.
            {
                var response = this.Request.CreateResponse(HttpStatusCode.Created, true);
                FormsAuthentication.SetAuthCookie(user.UserName, false);
    
                return response;
            }
    
            return this.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Invalid username or password");
        }
        return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState);
    }
    
  • Авторизация Использование библиотеки JWT для ограничения содержимого.

    config.MessageHandlers.Add(new JsonWebTokenValidationHandler
    {
      Audience = "123",
      SymmetricKey = "456"
    });
    
  • Мои методы API

    [Authorize]
    public IEnumerable<string> Get()
    {
     return new string[] { "value1", "value2" };
    }
    
4b9b3361

Ответ 1

Использовать ли аутентификацию cookie или (предъявитель) токены все еще зависит от типа приложения, которое у вас есть. И насколько я знаю, пока нет лучшей практики. Но поскольку вы работаете в SPA и уже используете JWT-библиотеку, я бы предпочел использовать подход, основанный на токенах.

К сожалению, я не могу помочь вам с ASP.NET, но обычно библиотеки JWT генерируют и проверяют токен для вас. Все, что вам нужно сделать, это вызвать generate или encode учетные данные (и секрет) и verify или decode на токене, отправленном с каждым запросом. И вам не нужно сохранять какое-либо состояние на сервере и не нужно отправлять cookie, что вы, вероятно, сделали с FormsAuthentication.SetAuthCookie(user.UserName, false).

Я уверен, что в вашей библиотеке приведен пример использования меток генерации/кодирования и проверки/декодирования.

Таким образом, создание и проверка не является чем-то, что вы делаете на стороне клиента.

Поток выглядит примерно так:

  • Клиент отправляет пользователю учетные данные для входа на сервер.
  • Сервер аутентифицирует учетные данные и отвечает сгенерированным токеном.
  • Клиент хранит токен где-то (локальное хранилище, файлы cookie или просто в памяти).
  • Клиент отправляет токен в качестве заголовка авторизации для каждого запроса на сервер.
  • Сервер проверяет токен и соответственно выполняет либо отправку запрошенного ресурса, либо 401 (или что-то подобное).

Шаг 1 и 3:

app.controller('UserController', function ($http, $window, $location) {
    $scope.signin = function(user) {
    $http.post(uri + 'account/signin', user)
        .success(function (data) {
            // Stores the token until the user closes the browser window.
            $window.sessionStorage.setItem('token', data.token);
            $location.path('/');
        })
        .error(function () {
            $window.sessionStorage.removeItem('token');
            // TODO: Show something like "Username or password invalid."
        });
    };
});

sessionStorage сохраняет данные до тех пор, пока пользователь открывает страницу. В случае, если вы хотите самостоятельно обрабатывать время истечения срока действия, вместо этого вы можете использовать localStorage. Интерфейс тот же.

Шаг 4:

Чтобы отправить токен при каждом запросе на сервер, вы можете использовать то, что Angular вызывает Interceptor. Все, что вам нужно сделать, это получить ранее сохраненный токен (если есть) и прикрепить его как заголовок ко всем исходящим запросам:

app.factory('AuthInterceptor', function ($window, $q) {
    return {
        request: function(config) {
            config.headers = config.headers || {};
            if ($window.sessionStorage.getItem('token')) {
                config.headers.Authorization = 'Bearer ' + $window.sessionStorage.getItem('token');
            }
            return config || $q.when(config);
        },
        response: function(response) {
            if (response.status === 401) {
                // TODO: Redirect user to login page.
            }
            return response || $q.when(response);
        }
    };
});

// Register the previously created AuthInterceptor.
app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('AuthInterceptor');
});

И обязательно используйте SSL!