Daha güzel bir demo yapma ve bu hizmetlerden bazılarını kullanılabilir bir modül haline getirme sürecindeyim, ama işte buradayım. Bu, bazı uyarılar etrafında çalışmak için karmaşık bir süreçtir, bu yüzden orada durun. Bunu birkaç parçaya bölmeniz gerekecek.
Bu şişeye bir bakın .
İlk olarak, kullanıcının kimliğini saklamak için bir hizmete ihtiyacınız vardır. Buna ben diyorum principal
. Kullanıcının oturum açıp açmadığını kontrol edebilir ve istek üzerine kullanıcının kimliği hakkında temel bilgileri temsil eden bir nesneyi çözebilir. Bu, ihtiyacınız olan her şey olabilir, ancak temel bilgiler bir görünen ad, bir kullanıcı adı, muhtemelen bir e-posta ve bir kullanıcının ait olduğu roller olacaktır (bu, uygulamanız için geçerliyse). Müdür ayrıca rol kontrolleri yapma yöntemlerine de sahiptir.
.factory('principal', ['$q', '$http', '$timeout',
function($q, $http, $timeout) {
var _identity = undefined,
_authenticated = false;
return {
isIdentityResolved: function() {
return angular.isDefined(_identity);
},
isAuthenticated: function() {
return _authenticated;
},
isInRole: function(role) {
if (!_authenticated || !_identity.roles) return false;
return _identity.roles.indexOf(role) != -1;
},
isInAnyRole: function(roles) {
if (!_authenticated || !_identity.roles) return false;
for (var i = 0; i < roles.length; i++) {
if (this.isInRole(roles[i])) return true;
}
return false;
},
authenticate: function(identity) {
_identity = identity;
_authenticated = identity != null;
},
identity: function(force) {
var deferred = $q.defer();
if (force === true) _identity = undefined;
// check and see if we have retrieved the
// identity data from the server. if we have,
// reuse it by immediately resolving
if (angular.isDefined(_identity)) {
deferred.resolve(_identity);
return deferred.promise;
}
// otherwise, retrieve the identity data from the
// server, update the identity object, and then
// resolve.
// $http.get('/svc/account/identity',
// { ignoreErrors: true })
// .success(function(data) {
// _identity = data;
// _authenticated = true;
// deferred.resolve(_identity);
// })
// .error(function () {
// _identity = null;
// _authenticated = false;
// deferred.resolve(_identity);
// });
// for the sake of the demo, fake the lookup
// by using a timeout to create a valid
// fake identity. in reality, you'll want
// something more like the $http request
// commented out above. in this example, we fake
// looking up to find the user is
// not logged in
var self = this;
$timeout(function() {
self.authenticate(null);
deferred.resolve(_identity);
}, 1000);
return deferred.promise;
}
};
}
])
İkincisi, kullanıcının gitmek istediği durumu kontrol eden, oturum açtıklarından emin olan (gerekirse; oturum açma, şifre sıfırlama vb. İçin gerekli değildir) bir rol hizmetine ihtiyacınız vardır ve ardından bir rol kontrolü yapar (uygulamanız buna ihtiyaç duyar). Kimlik doğrulaması yapılmazsa, oturum açma sayfasına gönderin. Kimlik doğruları doğrulanmış ancak bir rol denetiminde başarısız olmuşlarsa, erişim reddedilen bir sayfaya gönderin. Ben buna hizmet diyorum authorization
.
.factory('authorization', ['$rootScope', '$state', 'principal',
function($rootScope, $state, principal) {
return {
authorize: function() {
return principal.identity()
.then(function() {
var isAuthenticated = principal.isAuthenticated();
if ($rootScope.toState.data.roles
&& $rootScope.toState
.data.roles.length > 0
&& !principal.isInAnyRole(
$rootScope.toState.data.roles))
{
if (isAuthenticated) {
// user is signed in but not
// authorized for desired state
$state.go('accessdenied');
} else {
// user is not authenticated. Stow
// the state they wanted before you
// send them to the sign-in state, so
// you can return them when you're done
$rootScope.returnToState
= $rootScope.toState;
$rootScope.returnToStateParams
= $rootScope.toStateParams;
// now, send them to the signin state
// so they can log in
$state.go('signin');
}
}
});
}
};
}
])
Şimdi tüm is dinlemesini yapmak gerekir ui-router
's $stateChangeStart
. Bu size mevcut durumu, gitmek istedikleri durumu inceleme ve yetkilendirme kontrolünüzü ekleme şansı verir. Başarısız olursa, rota geçişini iptal edebilir veya farklı bir rotaya değiştirebilirsiniz.
.run(['$rootScope', '$state', '$stateParams',
'authorization', 'principal',
function($rootScope, $state, $stateParams,
authorization, principal)
{
$rootScope.$on('$stateChangeStart',
function(event, toState, toStateParams)
{
// track the state the user wants to go to;
// authorization service needs this
$rootScope.toState = toState;
$rootScope.toStateParams = toStateParams;
// if the principal is resolved, do an
// authorization check immediately. otherwise,
// it'll be done when the state it resolved.
if (principal.isIdentityResolved())
authorization.authorize();
});
}
]);
Bir kullanıcının kimliğini izlemeyle ilgili zor kısım, daha önce kimlik doğrulaması yaptıysanız (örneğin, önceki bir oturumdan sonra sayfayı ziyaret edip bir çerezde bir kimlik bilgisi jetonu kaydettiyseniz veya belki de sayfayı yenilediğinizde) veya bir bağlantıdan URL'ye düştü). Çalışma şekli nedeniyle, ui-router
kimlik doğrulaması kontrol etmeden önce kimliğinizi bir kez çözmeniz gerekir. Bunu resolve
durum yapılandırmanızdaki seçeneği kullanarak yapabilirsiniz . Tüm eyaletlerin miras aldığı site için bir ana eyaletim var, bu da yöneticiyi başka bir şey gerçekleşmeden çözülmeye zorluyor.
$stateProvider.state('site', {
'abstract': true,
resolve: {
authorize: ['authorization',
function(authorization) {
return authorization.authorize();
}
]
},
template: '<div ui-view />'
})
Burada başka bir sorun daha var ... resolve
sadece bir kez çağrılıyor. Kimlik arama vaadiniz tamamlandığında, çözüm temsilcisini tekrar çalıştırmaz. Bu nedenle, kimlik doğrulama kontrollerinizi iki yerde yapmak zorundayız: bir kez kimlik vaatlerinize çözümlenerek resolve
, uygulamanızın ilk kez yüklenmesini kapsar ve bir kez $stateChangeStart
de çözünürlük yapıldığı takdirde, eyaletler arasında dolaştığınız her zamanı kapsar.
Tamam, şimdiye kadar ne yaptık?
- Kullanıcının oturum açıp açmadığını uygulamanın ne zaman yüklediğini kontrol ederiz.
- Giriş yapan kullanıcı hakkındaki bilgileri takip ediyoruz.
- Kullanıcının oturum açmasını gerektiren durumlar için oturum açma durumuna yönlendiriyoruz.
- Erişme yetkileri yoksa, bunları erişim reddedildi durumuna yönlendiririz.
- Giriş yapmaları gerekiyorsa, kullanıcıları istedikleri orijinal duruma geri yönlendirmek için bir mekanizmamız var.
- Bir kullanıcının oturumunu kapatabiliriz (kimlik doğrulama biletinizi yöneten herhangi bir istemci veya sunucu koduyla uyumlu olarak bağlanması gerekir).
- Biz yok oturum açma sayfasına geri onların tarayıcınızı yeniden veya bir bağlantıyı açılan her zaman kullanıcıları göndermek gerekiyor.
Buradan nereye gidiyoruz? Eh, sen Oturum açmayı gerektiren bölgelere halinde devletleri organize edebilirsiniz. Sen ekleyerek kimlik doğrulaması / yetkili kullanıcıları gerektirebilirsiniz data
ile roles
(eğer devralma kullanmak isterseniz veya bunların bir ebeveyn), bu ülkelere. Burada, bir kaynağı Yöneticilerle kısıtlıyoruz:
.state('restricted', {
parent: 'site',
url: '/restricted',
data: {
roles: ['Admin']
},
views: {
'content@': {
templateUrl: 'restricted.html'
}
}
})
Artık kullanıcıların bir rotaya nelere erişebileceğini eyalet bazında kontrol edebilirsiniz. Başka endişeleriniz var mı? Giriş yapılıp yapılmadığına bağlı olarak görünümün yalnızca bir bölümünü değiştirebilir misiniz? Sorun değil. Bir şablonu veya öğeyi koşullu olarak görüntülemenin çeşitli yollarından herhangi biriyle principal.isAuthenticated()
veya hatta kullanın principal.isInRole()
.
İlk olarak, principal
bir denetleyiciye veya herhangi bir şeye enjekte edin ve görünümünüzde kolayca kullanabilmeniz için kapsama yapıştırın:
.scope('HomeCtrl', ['$scope', 'principal',
function($scope, principal)
{
$scope.principal = principal;
});
Bir öğeyi gösterme veya gizleme:
<div ng-show="principal.isAuthenticated()">
I'm logged in
</div>
<div ng-hide="principal.isAuthenticated()">
I'm not logged in
</div>
Vb, vb. Her neyse, örnek uygulamanızda, ana sayfa için kimliği doğrulanmamış kullanıcıların uğramasına izin verecek bir durumunuz olur. Oturum açma veya kaydolma durumlarına bağlantıları olabilir veya bu formların o sayfada yerleşik olmasını sağlayabilirler. Sana nasıl uyarsa.
Gösterge tablosu sayfalarının tümü, kullanıcıların oturum açmasını ve örneğin bir User
rol üyesi olmasını gerektiren bir durumdan miras alabilir . Tartıştığımız tüm yetkilendirme konuları oradan akacaktır.