AngularJS: Tek Sayfa Uygulamasında kimlik doğrulamayı kullanmak için temel örnek


100

Ben yeniyim angularjs ve öğretici geçirdi ve bunun için bir fikir var.

Projem için, RESTuç noktaların her birinin kimliğinin doğrulanması gereken hazır bir arka ucum var .

Ne yapmak istiyorum
a.) Projem için tek bir sayfam olsun istiyorum http://myproject.com.
b.) Bir kullanıcı, oturum açıp açmadığına bağlı olarak tarayıcıda URL'ye ulaştığında, kendisine aynı url altında bir ana sayfa / görünüm veya oturum açma sayfası / görünüm sunulur http://myproject.com.
c.) Bir kullanıcı oturum açmadıysa, formu doldurur ve sunucu bir USER_TOKENoturumda oturumu ayarlar , böylece uç noktalara yapılan diğer tüm istekler, aşağıdakilere göre doğrulanır:USER_TOKEN

Karışıklıklarım
a.) AngularJS kullanarak istemci tarafı kimlik doğrulamasını nasıl idare edebilirim? Burayı ve burayı gördüm ama nasıl kullanacağımı anlamadım
b.) Kullanıcının aynı url ile oturum açıp açmadığına göre kullanıcıya nasıl farklı görünümler sunabilirimhttp://myproject.com

Angular.js'yi ilk kez kullanıyorum ve nasıl başlayacağım konusunda gerçekten kafam karışıyor. Herhangi bir tavsiye ve / veya kaynak çok takdir edilmektedir.


Lütfen aşağıdaki makaleye bir göz atın frederiknakstad.com/…
Ajay Beniwal

1
@MichaelCalkins sadece bir bağlantı yerleştirmek yapıcı değildir. En azından bağlantının ne sağlayacağını söylemelisin.
Dave Gordon

Benim b: AngularJS Erişim Kontrolü ve Kimlik Doğrulama coderwall.com/p/f6brkg
Michael J. Calkins

OAuth ekibinin bunun için harika bir kitaplığı var andreareginato.github.io/oauth-ng
Faktor 10

Yanıtlar:


48

Bu makaleyi temel olarak özetleyen bir github deposu oluşturdum: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec

ng-login Github deposu

Plunker

Mümkün olduğunca iyi açıklamaya çalışacağım, umarım bazılarınıza yardım ederim:

(1) app.js: Uygulama tanımında kimlik doğrulama sabitlerinin oluşturulması

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) Yetkilendirme Hizmeti: Aşağıdaki tüm işlevler, auth.js hizmetinde uygulanır. $ Http hizmeti, kimlik doğrulama prosedürleri için sunucuyla iletişim kurmak için kullanılır. Ayrıca, kullanıcının belirli bir eylemi gerçekleştirmesine izin veriliyorsa, yetkilendirmeyle ilgili işlevleri de içerir.

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) Oturum: Kullanıcı verilerini saklamak için bir tekli. Buradaki uygulama size bağlıdır.

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) Ana denetleyici: Bunu uygulamanızın "ana" işlevi olarak düşünün, tüm denetleyiciler bu denetleyiciden devralır ve bu, uygulamanın kimlik doğrulamasının omurgasını oluşturur.

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

(5) Erişim kontrolü: Belirli yollara erişimi reddetmek için 2 adım uygulanmalıdır:

a) Aşağıda görülebileceği gibi ui yönlendiricinin $ stateProvider hizmetinde her yola erişmesine izin verilen rollerin verilerini ekleyin (aynısı ngRoute için de geçerli olabilir).

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

b) $ rootScope üzerinde. $ on ('$ stateChangeStart'), kullanıcı yetkili değilse durum değişikliğini önlemek için işlevi ekleyin.

$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) Yetkilendirme engelleyicisi: Bu uygulanmıştır, ancak bu kodun kapsamı kontrol edilemez. Her $ http talebinden sonra, bu engelleyici durum kodunu kontrol eder, eğer aşağıdakilerden biri döndürülürse, kullanıcıyı tekrar oturum açmaya zorlamak için bir olay yayınlar.

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 1. makalede belirtildiği gibi, form verilerinin otomatik doldurulmasına ilişkin bir hata, directives.js'de bulunan yönergeyi ekleyerek kolayca önlenebilir.

PS2 Bu kod, farklı rotaların görülmesine izin vermek veya gösterilmesi amaçlanmayan içeriği görüntülemek için kullanıcı tarafından kolayca değiştirilebilir. Mantık sunucu tarafında uygulanmalıdır, bu sadece ng-uygulamanızda işleri düzgün bir şekilde göstermenin bir yoludur.


1
İstemci tarafı mantığına başımı döndürmek için rehberinizi takip ediyordum. Bu gerçekten iyi!! Seansları manuel olarak yok etmekle ilgili bir şeyi kaçırdım, ancak bir şeyleri de denemeli ve kırmalıyız!
Sebastialonso

~~ bu satırı doğru anladığımdan emin değilim: authService.login() = [...]bu köşeli parantezler şöyle bir şey ifade edecek $http.get(url, {uID, pwd}mi? ~~ tamam, plunker'a baktım, dediğim gibi XD
netalex

1
cevabınızı sunucu tarafı için genişletebilir misiniz?
sorgu

25

Yaklaşımı beğendim ve ön uçta kimlik doğrulama ile ilgili herhangi bir şey yapmadan sunucu tarafında uyguladım

En son uygulamamdaki 'tekniğim' .. müşteri Auth umurunda değil. Uygulamadaki her şey önce bir oturum açma gerektirir, bu nedenle sunucu, oturumda mevcut bir kullanıcı tespit edilmedikçe her zaman bir oturum açma sayfası sunar. Session.user bulunursa, sunucu sadece index.html'yi gönderir. Bam: -o

"Andrew Joslin" in yorumuna bakın.

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


3
bir web api ise? Cevabınızı alamadım sanırım :(
Leandro De Mello Fagundes

1
Kullanıcı adını görüntülemek isterseniz ne olur? Ya da kullanıcı adı uç nokta URL'lerinde olan bir hizmetle konuşuyorsanız?
perrygeo

2
üzgünüm ama cevabı anlamadım. seansı açısal olarak nasıl idare edersiniz? session.user kümesi nerede? bunun bir kod örneğini yapabilir misiniz lütfen? teşekkür ederim
François Romain

4
Oturumlar sunucu tarafında değil istemci tarafında işlenir, istemci belirteci kaydeder ve yaptığı her isteğin bir parçası olarak gönderir. Sunucu belirteci doğrular ve isteği işler
daydreamer

4
Bunu anlayan biri bu yanıtı geri kalanımız için düzenleyebilir mi lütfen?
Alojz Janez

14

Burada benzer bir soruyu yanıtladım: AngularJS Authentication + RESTful API


UserApp için korumalı / genel yolları destekleyen, oturum açma / oturum kapatma sırasında yeniden yönlendirme, durum kontrolleri için sinyal verme, oturum belirtecini bir tanımlama bilgisinde, olaylarda vb. Depolayan bir AngularJS modülü yazdım .

Şunlardan birini yapabilirsiniz:

  1. Modülü değiştirin ve kendi API'nize ekleyin veya
  2. Modülü UserApp (bulut tabanlı bir kullanıcı yönetimi API'si) ile birlikte kullanın

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

UserApp kullanırsanız, kullanıcı işleri için herhangi bir sunucu tarafı kodu yazmanız gerekmez (bir belirteci doğrulamaktan daha fazlası). Al Codecademy üzerine ders denemek için.

İşte nasıl çalıştığına dair bazı örnekler:

  • Hangi yolların herkese açık olması gerektiği ve bunun hangi yolun oturum açma formu olduğu nasıl belirlenir:

    $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()Rota Eğer kullanıcılar girdikten sonra yönlendirilecek istediğiniz yere ayarlanmalıdır. Misal:

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

  • Hata işlemeli giriş formu:

    <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>
  • Hata işleme içeren kayıt formu:

    <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>
  • Çıkış bağlantısı:

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

    (Oturumu sonlandırır ve oturum açma yoluna yönlendirir)

  • Kullanıcı özelliklerine erişin:

    Kullanıcı özelliklerine userhizmet kullanılarak erişilir , örneğin:user.current.email

    Veya şablonda: <span>{{ user.email }}</span>

  • Yalnızca oturum açıldığında görünür olması gereken öğeleri gizle:

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

  • İzinlere göre bir öğe gösterin:

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

Ve arka uç hizmetlerinizin kimliğini doğrulamak için, yalnızca user.token()oturum belirtecini almak ve AJAX isteğiyle göndermek için kullanın. Arka uçta, belirtecin geçerli olup olmadığını kontrol etmek için UserApp API'yi (UserApp kullanıyorsanız) kullanın.

Yardıma ihtiyacın olursa bana haber ver!


"Modülü değiştirip kendi API'nize nasıl ekleyebilirim" ?
Pureferret

2

Angularjs'de UI bölümünü, hizmeti, Yönergeleri ve kullanıcı arabirimini temsil eden tüm angularj parçalarını oluşturabilirsiniz. Üzerinde çalışmak güzel bir teknoloji.

Bu teknolojiye yeni giren ve "Kullanıcının" kimliğini doğrulamak isteyen biri olarak, bunu c # web api'nin gücüyle yapmayı öneriyorum. bunun için, kullanıcının kimliğini doğrulamak için güçlü bir güvenlik mekanizması oluşturmanıza yardımcı olacak OAuth spesifikasyonunu kullanabilirsiniz. WebApi'yi OAuth ile oluşturduktan sonra, jeton için bu api'yi aramanız gerekir:

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

ve jetonu aldıktan sonra, Token'ın yardımıyla angularjs'den kaynakları talep edersiniz ve OAuth spesifikasyonu ile web Api'de güvende tutulan kaynağa erişirsiniz.

Daha fazla yardım için lütfen aşağıdaki makaleye göz atın: -

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


1

Her JSON yanıtının bir özellik içermesi gerektiğini (örneğin, {Authenticated: false}) ve istemcinin bunu her seferinde test etmesi gerektiğini düşünüyorum: false ise, Angular controller / service oturum açma sayfasına "yeniden yönlendirecektir".

Ve kullanıcı JSON'u yakalar ve bool'u True olarak değiştirirse ne olur?

Bence bu tür şeyler yapmak için asla müşteri tarafına güvenmemelisiniz. Kullanıcının kimliği doğrulanmamışsa, sunucu yalnızca bir oturum açma / hata sayfasına yönlendirmelidir.


2
Şunu kontrol edin: github.com/witoldsz/angular-http-auth - durdurucu sunucu yanıt durum kodunu kontrol eder ve 403 ise ('oturum açma gerekli') bir olay yayınlar, böylece onu uygulama içinde yakalayabilir ve oturum açma kutusunu görüntüleyebilirsiniz.
aherok

10
Cevapları kullanarak birbirinize cevap vermeyi bırakın. Yorumlar bunun için!
Soviut

@aherok öneri, yorumunuz bir cevaba yükseltilmeli, zamanında en üste oylanacaktır. gerisi sadece gürültü.
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;
 
    };
 

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.