AngularJS: Основний приклад використання автентифікації в застосуванні для однієї сторінки


100

Я новачок у AngularJS і пройшов їхній підручник, і я відчув це.

У мене є готовий підхід для мого проекту, де кожну з RESTкінцевих точок потрібно автентифікувати.

Що я хочу зробити
.) Я хочу мати одну сторінку для свого проекту http://myproject.com.
b.) Після того, як користувач потрапляє на URL-адресу у веб-переглядачі, виходячи з того, чи користувач увійшов чи ні, йому відображається домашня сторінка / перегляд або сторінка входу / перегляд під тим же URL-адресою http://myproject.com.
c.) якщо користувач не входить у систему, він заповнює форму і сервер встановлює USER_TOKENсеанс, тому всі подальші запити до кінцевих точок будуть автентифіковані на основіUSER_TOKEN

Мої плутанини
a.) Як я можу обробити автентифікацію на стороні клієнта за допомогою AngularJS? Я бачив тут і тут, але не розумів, як ними користуватися.
B. Як я можу представити різні погляди користувачеві на основі того, чи користувач увійшов чи не під одним URLhttp://myproject.com

Я використовую angular.js вперше і дуже заплутався, як почати. Будь-які поради та / або ресурси дуже вдячні.


Перегляньте статтю нижче frederiknakstad.com/…
Ajay Beniwal

1
@MichaelCalkins просто розміщення посилання не є конструктивним. Ви повинні хоча б сказати, що посилання надасть.
Дейв Гордон

Мій b: AngularJS Контроль доступу та автентифікація coderwall.com/p/f6brkg
Майкл Дж. Калкінс

Команда в OAuth має чудову бібліотеку для цього andreareginato.github.io/oauth-ng
Faktor 10

Відповіді:


48

Я створив github repo, підсумовуючи цю статтю в основному: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec

ng-логін Github repo

Плункер

Я спробую пояснити якомога краще, сподіваюся, я допоможу деяким з вас там:

(1) app.js: створення констант автентифікації за визначенням програми

var loginApp = angular.module('loginApp', ['ui.router', 'ui.bootstrap'])
/*Constants regarding user login defined here*/
.constant('USER_ROLES', {
    all : '*',
    admin : 'admin',
    editor : 'editor',
    guest : 'guest'
}).constant('AUTH_EVENTS', {
    loginSuccess : 'auth-login-success',
    loginFailed : 'auth-login-failed',
    logoutSuccess : 'auth-logout-success',
    sessionTimeout : 'auth-session-timeout',
    notAuthenticated : 'auth-not-authenticated',
    notAuthorized : 'auth-not-authorized'
})

(2) Служба Auth: Усі наступні функції реалізовані в службі auth.js. Служба $ http використовується для зв'язку з сервером для процедур аутентифікації. Також містить функції авторизації, тобто якщо користувачеві дозволено виконувати певну дію.

angular.module('loginApp')
.factory('Auth', [ '$http', '$rootScope', '$window', 'Session', 'AUTH_EVENTS', 
function($http, $rootScope, $window, Session, AUTH_EVENTS) {

authService.login() = [...]
authService.isAuthenticated() = [...]
authService.isAuthorized() = [...]
authService.logout() = [...]

return authService;
} ]);

(3) Сесія: Односортний для збереження даних користувачів. Реалізація тут залежить від вас.

angular.module('loginApp').service('Session', function($rootScope, USER_ROLES) {

    this.create = function(user) {
        this.user = user;
        this.userRole = user.userRole;
    };
    this.destroy = function() {
        this.user = null;
        this.userRole = null;
    };
    return this;
});

(4) Батьківський контролер: Розгляньте це як "основну" функцію вашої програми, всі контролери успадковують цей контролер, і він є основою аутентифікації цього додатка.

<body ng-controller="ParentController">
[...]
</body>

(5) Контроль доступу: Щоб заборонити доступ на певних маршрутах, необхідно здійснити 2 кроки:

а) Додайте дані про ролі, дозволені для доступу до кожного маршруту, в службі $ stateProvider маршрутизатора, як видно нижче (те саме може працювати для ngRoute).

.config(function ($stateProvider, USER_ROLES) {
  $stateProvider.state('dashboard', {
    url: '/dashboard',
    templateUrl: 'dashboard/index.html',
    data: {
      authorizedRoles: [USER_ROLES.admin, USER_ROLES.editor]
    }
  });
})

b) На $ rootScope. $ on ('$ stateChangeStart') додайте функцію, щоб запобігти зміні стану, якщо користувач не отримав авторизацію.

$rootScope.$on('$stateChangeStart', function (event, next) {
    var authorizedRoles = next.data.authorizedRoles;
    if (!Auth.isAuthorized(authorizedRoles)) {
      event.preventDefault();
      if (Auth.isAuthenticated()) {
        // user is not allowed
        $rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
      } else {
        // user is not logged in
        $rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
      }
    }
});

(6) Auth перехоплювач: Це реалізовано, але його неможливо перевірити на предмет дії цього коду. Після кожного запиту $ http, цей перехоплювач перевіряє код статусу, якщо повернеться одне із наведених нижче, то він транслює подію, щоб змусити користувача знову входити в систему.

angular.module('loginApp')
.factory('AuthInterceptor', [ '$rootScope', '$q', 'Session', 'AUTH_EVENTS',
function($rootScope, $q, Session, AUTH_EVENTS) {
    return {
        responseError : function(response) {
            $rootScope.$broadcast({
                401 : AUTH_EVENTS.notAuthenticated,
                403 : AUTH_EVENTS.notAuthorized,
                419 : AUTH_EVENTS.sessionTimeout,
                440 : AUTH_EVENTS.sessionTimeout
            }[response.status], response);
            return $q.reject(response);
        }
    };
} ]);

PS Помилка з автоматичним заповненням даних форми, як зазначено в першій статті, можна легко уникнути, додавши директиву, що входить до direc.s.

PS2 Цей код може бути легко налаштований користувачем, щоб можна було бачити різні маршрути або відображати вміст, який не передбачався для відображення. Логіка ОБОВ'ЯЗКОВО бути реалізованою на сервері, це лише спосіб правильно показати речі у вашому ng-додатку.


1
Я слідкую за вашим керівництвом, щоб обернути голову за логікою на стороні клієнта. Це дійсно добре !! Я щось пропустив про ручне знищення сеансів, але ми також повинні експериментувати і порушувати речі!
Себастіалонсо

~~ не впевнений, чи правильно я розумію цей рядок: authService.login() = [...]ці квадратні дужки будуть означати щось на зразок $http.get(url, {uID, pwd}? ~~ ок, заглянув у планкер, це було так, як я сказав XD
netalex

1
чи можете ви розгорнути свою відповідь на стороні сервера?
запит

25

Мені подобається підхід і реалізовано його на стороні сервера, не роблячи жодної речі, пов’язаної з автентифікацією, на передній панелі

Моя "техніка" в моєму останньому додатку - це .. клієнт не хвилює Auth. Кожна річ у додатку спочатку потребує входу, тому сервер завжди завжди обслуговує сторінку входу, якщо в сеансі не виявлено наявного користувача. Якщо знайдено session.user, сервер просто надсилає index.html. Бам: -о

Шукайте коментар "Ендрю Джосліна".

https://groups.google.com/forum/?fromgroups=#!searchin/angular/authentication/angular/POXLTi_JUgg/VwStpoWCPUQJ


3
якщо його веб-api? Я не отримав вашої відповіді, я здогадуюсь :(
Леандро Де Мелло Фагундес

1
Що робити, якщо ви хочете відобразити ім’я користувача? Або якщо ви спілкуєтесь із службою з ім’ям користувача у URL-адресах кінцевої точки?
perrygeo

2
вибачте, але я не розумію відповіді. як ви обробляєте сеанс у кутку? де встановлено session.user? ви можете зробити приклад коду цього, будь ласка? дякую
Франсуа Ромен

4
Сеанси обробляються на стороні клієнта, а не на сервері, клієнт зберігає маркер і відправляє його як частину кожного запиту, який він робить. Сервер перевіряє маркер і обробляє запит
daydreamer

4
Чи може хтось, хто це розуміє, відредагувати цю відповідь для решти нас?
Alojz Janez

14

Я відповів на подібне запитання тут: AngularJS Authentication + RESTful API


Я написав модуль AngularJS для UserApp, який підтримує захищені / загальнодоступні маршрути, перенаправлення під час входу / виходу, серцебиття для перевірки стану, зберігає маркер сесії у файлі cookie, подіях тощо.

Ви можете:

  1. Змініть модуль і додайте його до власного API, або
  2. Використовуйте модуль разом з UserApp (хмарний API управління користувачем)

https://github.com/userapp-io/userapp-angular

Якщо ви користуєтеся UserApp, вам не доведеться писати будь-який код на стороні сервера для користувачів (більше ніж перевірка маркера). Спробуйте курс з Codecademy, щоб спробувати його.

Ось кілька прикладів того, як це працює:

  • Як вказати маршрути, які мають бути загальнодоступними та який маршрут - це форма для входу:

    $routeProvider.when('/login', {templateUrl: 'partials/login.html', public: true, login: true});
    $routeProvider.when('/signup', {templateUrl: 'partials/signup.html', public: true});
    $routeProvider.when('/home', {templateUrl: 'partials/home.html'});

    .otherwise()Маршрут повинен бути встановлений в положення, де ви хочете , щоб ваші користувачі будуть перенаправлені після входу в систему . Приклад:

    $routeProvider.otherwise({redirectTo: '/home'});

  • Форма для входу з помилкою обробки

    <form ua-login ua-error="error-msg">
        <input name="login" placeholder="Username"><br>
        <input name="password" placeholder="Password" type="password"><br>
        <button type="submit">Log in</button>
        <p id="error-msg"></p>
    </form>
  • Форма реєстрації з обробкою помилок:

    <form ua-signup ua-error="error-msg">
      <input name="first_name" placeholder="Your name"><br>
      <input name="login" ua-is-email placeholder="Email"><br>
      <input name="password" placeholder="Password" type="password"><br>
      <button type="submit">Create account</button>
      <p id="error-msg"></p>
    </form>
  • Посилання на вихід:

    <a href="#" ua-logout>Log Out</a>

    (Завершує сеанс і переспрямовує на маршрут входу)

  • Доступ до властивостей користувача:

    Доступ до властивостей користувача здійснюється за допомогою userсервісу, наприклад:user.current.email

    Або в шаблоні: <span>{{ user.email }}</span>

  • Сховати елементи, які мають бути видимими лише після входу:

    <div ng-show="user.authorized">Welcome {{ user.first_name }}!</div>

  • Показати елемент на основі дозволів:

    <div ua-has-permission="admin">You are an admin</div>

А для аутентифікації до своїх бек-енд-сервісів просто скористайтеся, user.token()щоб отримати маркер сеансу та надіслати його із запитом AJAX. Назад, використовуйте API UserApp (якщо ви використовуєте UserApp), щоб перевірити, чи маркер дійсний чи ні.

Якщо вам потрібна допомога, просто дайте мені знати!


Як би я "Змінив модуль і приєднав його до власного API" ?
Pureferret

2

У angularjs ви можете створити частину, сервіс, директиви та всю частину angularjs, яка представляє інтерфейс користувача. Приємно працювати над технологією.

Як і кожен, хто новачок у цій технології та хоче автентифікувати "Користувача", тоді я пропоную зробити це з використанням c # web api. для цього ви можете використовувати специфікацію OAuth, яка допоможе вам створити потужний механізм захисту для аутентифікації користувача. як тільки ви побудуєте WebApi з OAuth, вам потрібно зателефонувати в цей api:

var _login = function (loginData) {
 
        var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
 
        var deferred = $q.defer();
 
        $http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {
 
            localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName });
 
            _authentication.isAuth = true;
            _authentication.userName = loginData.userName;
 
            deferred.resolve(response);
 
        }).error(function (err, status) {
            _logOut();
            deferred.reject(err);
        });
 
        return deferred.promise;
 
    };
 

і як тільки ви отримаєте маркер, ви запитаєте ресурси від angularjs за допомогою Token та отримаєте доступ до ресурсу, який захищений у веб-апі з специфікацією OAuth.

Щоб отримати додаткову допомогу, перегляньте статтю нижче:

http://bitoftech.net/2014/06/09/angularjs-token-authentication-using-asp-net-web-api-2-owin-asp-net-identity/


1

Я думаю, що кожна відповідь JSON повинна містити властивість (наприклад, {автентифіковано: помилково}), і клієнт повинен її перевіряти кожен раз: якщо помилковий, то кутовий контролер / служба "перенаправлятиметься" на сторінку входу.

А що станеться, якщо користувач застане де JSON і змінить bool на True?

Я думаю, що вам ніколи не слід покладатися на сторону клієнта, щоб робити подібні речі. Якщо користувач не має автентифікації, сервер повинен просто перенаправити на сторінку входу / помилки.


2
Перевірте це: github.com/witoldsz/angular-http-auth - перехоплювач перевіряє код статусу відповіді сервера, і якщо він 403 (потрібний логін), він транслює подію, тож ви можете зафіксувати його всередині програми та відобразити вікно входу.
aherok

10
Перестаньте відповідати один одному, використовуючи відповіді. Ось до чого і коментарі!
Радянський

@aherok пропозиція, ваш коментар повинен бути запропонований до відповіді, він буде проголосований вгорі вчасно. решта - лише шум.
user237419

0

var _login = function (loginData) {
 
        var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
 
        var deferred = $q.defer();
 
        $http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {
 
            localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName });
 
            _authentication.isAuth = true;
            _authentication.userName = loginData.userName;
 
            deferred.resolve(response);
 
        }).error(function (err, status) {
            _logOut();
            deferred.reject(err);
        });
 
        return deferred.promise;
 
    };
 

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.