AngularJS: Ví dụ cơ bản để sử dụng xác thực trong Ứng dụng Trang đơn


100

Tôi mới làm quen với AngularJS và đã xem qua hướng dẫn của họ và có cảm nhận về nó.

Tôi có một chương trình phụ trợ cho dự án của mình đã sẵn sàng trong đó mỗi RESTđiểm cuối cần được xác thực.

Những gì tôi muốn làm
a.) Tôi muốn có một trang duy nhất cho dự án của mình http://myproject.com.
b.) Khi người dùng truy cập vào URL trong trình duyệt, dựa trên việc người dùng có đăng nhập hay không, họ sẽ thấy trang chủ / chế độ xem hoặc trang đăng nhập / chế độ xem dưới cùng một url http://myproject.com.
c.) nếu người dùng chưa đăng nhập, nó sẽ điền vào biểu mẫu và máy chủ đặt một USER_TOKENtrong phiên, do đó, tất cả các yêu cầu khác tới điểm cuối sẽ được xác thực dựa trênUSER_TOKEN

Sự nhầm lẫn của tôi
a.) Làm cách nào để xử lý xác thực phía máy khách bằng AngularJS? Tôi đã thấy ở đâyở đây nhưng không hiểu cách sử dụng chúng
. B.) Làm cách nào để trình bày các chế độ xem khác nhau cho người dùng dựa trên việc người dùng đã đăng nhập hay không theo cùng một urlhttp://myproject.com

Tôi đang sử dụng angle.js lần đầu tiên và thực sự bối rối không biết bắt đầu như thế nào. Mọi lời khuyên và / hoặc tài nguyên đều được đánh giá rất cao.


Vui lòng xem bài viết dưới đây frederiknakstad.com/…
Ajay Beniwal

1
@MichaelCalkins chỉ đặt một liên kết không mang tính xây dựng. Ít nhất bạn nên nói những gì liên kết sẽ cung cấp.
Dave Gordon

B của tôi: Kiểm soát truy cập và xác thực AngularJS coderwall.com/p/f6brkg
Michael J. Calkins

Nhóm tại OAuth có một thư viện tuyệt vời cho điều này andreareginato.github.io/oauth-ng
Faktor 10

Câu trả lời:


48

Về cơ bản, tôi đã tạo một repo github tóm tắt bài viết này: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-application-7bbf0346acec

ng-login Github repo

Plunker

Tôi sẽ cố gắng giải thích tốt nhất có thể, hy vọng tôi sẽ giúp một số bạn ở đó:

(1) app.js: Tạo hằng số xác thực trên định nghĩa ứng dụng

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) Dịch vụ xác thực: Tất cả các chức năng sau được triển khai trong dịch vụ auth.js. Dịch vụ $ http được sử dụng để giao tiếp với máy chủ cho các thủ tục xác thực. Cũng chứa các chức năng về ủy quyền, đó là nếu người dùng được phép thực hiện một hành động nhất định.

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) Phiên: Một singleton để giữ dữ liệu người dùng. Việc thực hiện ở đây phụ thuộc vào bạn.

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) Bộ điều khiển chính: Coi đây là chức năng "chính" của ứng dụng của bạn, tất cả các bộ điều khiển kế thừa từ bộ điều khiển này và nó là xương sống của việc xác thực ứng dụng này.

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

(5) Kiểm soát truy cập: Để từ chối truy cập trên các tuyến đường nhất định, bạn phải thực hiện 2 bước:

a) Thêm dữ liệu của các vai trò được phép truy cập từng tuyến, trên dịch vụ $ stateProvider của bộ định tuyến ui như có thể thấy bên dưới (tương tự có thể hoạt động cho ngRoute).

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

b) Trên $ rootScope. $ on ('$ stateChangeStart') thêm chức năng để ngăn thay đổi trạng thái nếu người dùng không được phép.

$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) Bộ đánh chặn xác thực: Điều này được triển khai, nhưng không thể kiểm tra trên phạm vi của mã này. Sau mỗi yêu cầu $ http, bộ chặn này sẽ kiểm tra mã trạng thái, nếu một trong các mã dưới đây được trả về, thì nó sẽ phát ra một sự kiện để buộc người dùng đăng nhập lại.

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 Có thể dễ dàng tránh được lỗi với tính năng tự động điền dữ liệu biểu mẫu như đã nêu trong bài viết đầu tiên bằng cách thêm chỉ thị được bao gồm trong chỉ thị .js.

PS2 Người dùng có thể dễ dàng tinh chỉnh mã này, để cho phép các tuyến đường khác nhau được nhìn thấy, hoặc hiển thị nội dung không được phép hiển thị. Logic PHẢI được triển khai phía máy chủ, đây chỉ là một cách để hiển thị mọi thứ đúng cách trên ng-app của bạn.


1
Tôi đã làm theo hướng dẫn của bạn để xoay quanh logic phía khách hàng. Nó thật sự tốt!! Tôi đã bỏ lỡ điều gì đó về việc hủy phiên theo cách thủ công, nhưng chúng tôi cũng phải thử nghiệm và phá vỡ mọi thứ!
Sebastialonso

~~ không chắc chắn nếu tôi hiểu đúng dòng đó: authService.login() = [...]những dấu ngoặc vuông sẽ đại diện cho một cái gì đó giống như $http.get(url, {uID, pwd}? ~~ ok, nhìn vào plunker, nó được như tôi đã nói XD
netalex

1
bạn có thể mở rộng câu trả lời của bạn cho phía máy chủ?
truy vấn

25

Tôi thích cách tiếp cận và triển khai nó ở phía máy chủ mà không thực hiện bất kỳ điều gì liên quan đến xác thực trên giao diện người dùng

'Kỹ thuật' của tôi trên ứng dụng mới nhất của tôi là .. khách hàng không quan tâm đến Auth. Mọi thứ trong ứng dụng đều yêu cầu đăng nhập trước, vì vậy máy chủ chỉ luôn cung cấp trang đăng nhập trừ khi người dùng hiện có được phát hiện trong phiên. Nếu tìm thấy session.user, máy chủ chỉ gửi index.html. Bam: -o

Hãy tìm bình luận của "Andrew Joslin".

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


3
nếu nó là một trang web? Tôi didnt có được câu trả lời của bạn tôi đoán :(
Leandro De Mello Fagundes

1
Nếu bạn muốn hiển thị tên người dùng thì sao? Hoặc nếu bạn đang nói chuyện với một dịch vụ có tên người dùng trong các URL điểm cuối?
perrygeo

2
xin lỗi, nhưng tôi không hiểu câu trả lời. làm thế nào để bạn xử lý phiên trong góc cạnh? session.user được đặt ở đâu? bạn có thể làm một ví dụ mã về điều này không? cảm ơn bạn
François Romain

4
Các phiên được xử lý ở phía máy khách chứ không phải phía máy chủ, máy khách lưu mã thông báo và gửi nó như một phần của mọi yêu cầu mà nó đưa ra. Máy chủ xác thực mã thông báo và xử lý yêu cầu
daydreamer ngày

4
Ai đó hiểu nó có thể chỉnh sửa câu trả lời này cho phần còn lại của chúng tôi không?
Alojz Janez

14

Tôi đã trả lời một câu hỏi tương tự ở đây: Xác thực AngularJS + API RESTful


Tôi đã viết một mô-đun AngularJS cho UserApp hỗ trợ các tuyến đường được bảo vệ / công khai, định tuyến lại khi đăng nhập / đăng xuất, nhịp tim để kiểm tra trạng thái, lưu trữ mã thông báo phiên trong cookie, sự kiện, v.v.

Bạn có thể:

  1. Sửa đổi mô-đun và đính kèm nó vào API của riêng bạn hoặc
  2. Sử dụng mô-đun cùng với UserApp (API quản lý người dùng dựa trên đám mây)

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

Nếu bạn sử dụng UserApp, bạn sẽ không phải viết bất kỳ mã phía máy chủ nào cho nội dung người dùng (hơn là xác thực mã thông báo). Tham gia khóa học trên Codecademy để dùng thử.

Dưới đây là một số ví dụ về cách nó hoạt động:

  • Cách chỉ định tuyến đường nào nên công khai và tuyến đường nào là biểu mẫu đăng nhập:

    $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'});

    Các .otherwise()tuyến đường nên được thiết lập đến nơi mà bạn muốn người dùng được chuyển hướng sau khi đăng nhập. Thí dụ:

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

  • Biểu mẫu đăng nhập có xử lý lỗi:

    <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>
  • Biểu mẫu đăng ký có xử lý lỗi:

    <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>
  • Liên kết đăng xuất:

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

    (Kết thúc phiên và chuyển hướng đến lộ trình đăng nhập)

  • Truy cập thuộc tính người dùng:

    Thuộc tính người dùng được truy cập bằng cách sử dụng userdịch vụ, ví dụ:user.current.email

    Hoặc trong mẫu: <span>{{ user.email }}</span>

  • Ẩn các phần tử chỉ hiển thị khi đã đăng nhập:

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

  • Hiển thị một phần tử dựa trên quyền:

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

Và để xác thực với các dịch vụ back-end của bạn, chỉ cần sử dụng user.token()để lấy mã thông báo phiên và gửi nó với yêu cầu AJAX. Ở phía cuối, hãy sử dụng API UserApp (nếu bạn sử dụng UserApp) để kiểm tra xem mã thông báo có hợp lệ hay không.

Nếu bạn cần bất kỳ sự giúp đỡ, chỉ cho tôi biết!


Làm cách nào để "Sửa đổi mô-đun và đính kèm nó vào API của riêng bạn" ?
Pureferret

2

Trong anglejs, bạn có thể tạo phần UI, dịch vụ, Directives và tất cả các phần của anglejs đại diện cho UI. Đó là công nghệ tốt để làm việc.

Với tư cách là bất kỳ ai mới sử dụng công nghệ này và muốn xác thực "Người dùng" thì tôi khuyên bạn nên làm điều đó với sức mạnh của c # web api. vì vậy bạn có thể sử dụng đặc tả OAuth sẽ giúp bạn xây dựng cơ chế bảo mật mạnh mẽ để xác thực người dùng. khi bạn xây dựng WebApi với OAuth, bạn cần gọi api đó cho mã thông báo:

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;
 
    };
 

và khi bạn nhận được mã thông báo thì bạn yêu cầu tài nguyên từ anglejs với sự trợ giúp của Mã thông báo và truy cập tài nguyên được giữ an toàn trong web Api với đặc tả OAuth.

Hãy xem bài viết dưới đây để được trợ giúp thêm: -

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


1

Tôi nghĩ rằng mọi phản hồi JSON phải chứa một thuộc tính (ví dụ: {authenticated: false}) và khách hàng phải kiểm tra nó mọi lúc: nếu sai, thì Angular controller / service sẽ "chuyển hướng" đến trang đăng nhập.

Và điều gì sẽ xảy ra nếu người dùng bắt de JSON và thay đổi bool thành True?

Tôi nghĩ rằng bạn không bao giờ nên dựa vào phía khách hàng để làm những việc này. Nếu người dùng không được xác thực, máy chủ sẽ chỉ chuyển hướng đến trang đăng nhập / lỗi.


2
Kiểm tra cái này: github.com/witoldsz/angular-http-auth - bộ chặn kiểm tra mã trạng thái phản hồi của máy chủ và nếu nó là 403 ('yêu cầu đăng nhập'), nó sẽ phát một sự kiện, vì vậy bạn có thể bắt nó bên trong ứng dụng và hiển thị hộp đăng nhập.
aherok

10
Ngừng trả lời nhau bằng câu trả lời. Đó là những gì các ý kiến ​​dành cho!
Soviut

@aherok gợi ý, bình luận của bạn nên được nâng cấp thành một câu trả lời, nó sẽ được bình chọn lên đầu trong thời gian. phần còn lại chỉ là tiếng ồn.
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;
 
    };
 

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.