मैं एक अच्छा प्रदर्शन करने के साथ-साथ एक उपयोगी मॉड्यूल में इन सेवाओं में से कुछ को साफ करने की प्रक्रिया में हूं, लेकिन यहां मैं आपके साथ आया हूं। कुछ कैविटीज़ के आसपास काम करने के लिए यह एक जटिल प्रक्रिया है, इसलिए इसमें लटके रहें। आपको इसे कई टुकड़ों में तोड़ना होगा।
इस डुबकी पर एक नज़र डालें ।
सबसे पहले, आपको उपयोगकर्ता की पहचान को संग्रहीत करने के लिए एक सेवा की आवश्यकता है। मैं इसे कॉल करता हूं principal
। यह देखने के लिए जाँच की जा सकती है कि उपयोगकर्ता लॉग इन है, और अनुरोध पर, यह उपयोगकर्ता की पहचान के बारे में आवश्यक जानकारी का प्रतिनिधित्व करने वाली वस्तु को हल कर सकता है। यह आप की जरूरत है जो कुछ भी हो सकता है, लेकिन अनिवार्य एक प्रदर्शन नाम होगा, एक उपयोगकर्ता नाम, संभवतः एक ईमेल, और भूमिकाएं जो एक उपयोगकर्ता की है (यदि यह आपके ऐप पर लागू होती है)। प्रिंसिपल के पास रोल चेक करने के तरीके भी हैं।
.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;
}
};
}
])
दूसरा, आपको एक ऐसी सेवा की आवश्यकता है जो उपयोगकर्ता को जिस राज्य में जाना चाहता है, उसकी जांच करता है, यह सुनिश्चित करता है कि वे लॉग इन हैं (यदि आवश्यक हो, साइनइन, पासवर्ड रीसेट, आदि के लिए आवश्यक नहीं है), और फिर एक भूमिका जांच (यदि आपका ऐप है) इसकी जरूरत है)। यदि वे प्रमाणित नहीं हैं, तो उन्हें साइन-इन पृष्ठ पर भेजें। यदि उन्हें प्रमाणित किया जाता है, लेकिन एक भूमिका जांच विफल हो जाती है, तो उन्हें एक एक्सेस अस्वीकृत पृष्ठ पर भेजें। मैं इस सेवा को कॉल करता हूं 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');
}
}
});
}
};
}
])
अब तुम सब है को सुन सब करने की ज़रूरत ui-router
है $stateChangeStart
। यह आपको वर्तमान स्थिति की जांच करने का मौका देता है, जिस राज्य में वे जाना चाहते हैं, और अपने प्राधिकरण की जांच डालें। यदि यह विफल रहता है, तो आप मार्ग परिवर्तन को रद्द कर सकते हैं, या किसी भिन्न मार्ग में परिवर्तन कर सकते हैं।
.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();
});
}
]);
किसी उपयोगकर्ता की पहचान को ट्रैक करने के बारे में मुश्किल हिस्सा यह देख रहा है कि क्या आपने पहले ही प्रमाणित कर लिया है (कहते हैं, आप पिछले सत्र के बाद पृष्ठ पर जा रहे हैं, और कुकी में एक ऑर्टिकल टोकन सहेजा है, या हो सकता है कि आपने पृष्ठ को हार्ड रिफ्रेश किया हो, या एक लिंक से एक यूआरएल पर गिरा दिया)। ui-router
काम करने के तरीके के कारण , आपको अपनी पहचान जाँचने से पहले एक बार अपनी पहचान का समाधान करने की आवश्यकता है। आप resolve
अपने राज्य कॉन्फ़िगरेशन में विकल्प का उपयोग करके ऐसा कर सकते हैं । साइट के लिए मेरे पास एक मूल राज्य है जो सभी राज्यों से विरासत में मिला है, जो प्रिंसिपल को कुछ और होने से पहले हल करने के लिए मजबूर करता है।
$stateProvider.state('site', {
'abstract': true,
resolve: {
authorize: ['authorization',
function(authorization) {
return authorization.authorize();
}
]
},
template: '<div ui-view />'
})
यहाँ एक और समस्या है ... resolve
केवल एक बार कॉल किया जाता है। एक बार पहचान के लिए आपका वादा पूरा होने पर, यह फिर से प्रतिनिधि प्रतिनिधि को नहीं चलाएगा। इसलिए हमें आपके दो स्थानों पर अपनी जाँच करनी है: एक बार अपने पहचान के वादे के अनुसार resolve
, जो पहली बार आपके ऐप के लोड को कवर करता है, और एक बार$stateChangeStart
यदि रिज़ॉल्यूशन हो चुका है, तो आप किसी भी समय राज्यों के चारों ओर नेविगेट करते हैं।
ठीक है, तो हमने अब तक क्या किया है?
- हम यह देखने के लिए जांचते हैं कि उपयोगकर्ता लॉग इन होने पर ऐप लोड करता है या नहीं।
- हम उपयोगकर्ता में लॉग इन के बारे में जानकारी ट्रैक करते हैं।
- हम उन्हें उन राज्यों के लिए राज्य में साइन इन करने के लिए पुनर्निर्देशित करते हैं जिनके लिए उपयोगकर्ता को लॉग इन करने की आवश्यकता होती है।
- यदि वे इसे एक्सेस करने के लिए प्राधिकरण नहीं रखते हैं, तो हम उन्हें एक एक्सेस अस्वीकृत राज्य में पुनर्निर्देशित करते हैं।
- यदि हमारे पास लॉग इन करने की आवश्यकता है, तो हमारे पास उपयोगकर्ताओं को मूल स्थिति में वापस लाने के लिए एक तंत्र है।
- हम एक उपयोगकर्ता को साइन आउट कर सकते हैं (आपके ग्राहक टिकट को प्रबंधित करने वाले किसी भी क्लाइंट या सर्वर कोड के साथ कॉन्सर्ट में वायर्ड होने की आवश्यकता है)।
- हमें हर बार अपने ब्राउज़र को पुनः लोड करने या किसी लिंक पर छोड़ने के लिए उपयोगकर्ताओं को साइन-इन पृष्ठ पर वापस भेजने की आवश्यकता नहीं है।
हम यहाँ से कहाँ जायेंगे? ठीक है, आप अपने राज्यों को उन क्षेत्रों में व्यवस्थित कर सकते हैं जिनमें साइन इन करने की आवश्यकता होती है। आप इन राज्यों के साथ (या यदि आप विरासत का उपयोग करना चाहते हैं, तो उनके data
साथ जोड़कर) प्रमाणित / अधिकृत उपयोगकर्ताओं की आवश्यकता हो सकती है roles
। यहाँ, हम एक संसाधन को Admins तक सीमित करते हैं:
.state('restricted', {
parent: 'site',
url: '/restricted',
data: {
roles: ['Admin']
},
views: {
'content@': {
templateUrl: 'restricted.html'
}
}
})
अब आप राज्य-दर-राज्य को नियंत्रित कर सकते हैं कि उपयोगकर्ता किस मार्ग तक पहुंच सकते हैं। कोई और चिंता? शायद वे लॉग इन हैं या नहीं, इसके आधार पर किसी दृश्य का केवल एक हिस्सा अलग-अलग हो सकता है? कोई दिक्कत नहीं है। principal.isAuthenticated()
या का भी उपयोग करेंprincipal.isInRole()
उन सभी तरीकों से भी जिनके साथ आप सशर्त रूप से टेम्पलेट या तत्व प्रदर्शित कर सकते हैं, का ।
सबसे पहले, principal
एक नियंत्रक या जो कुछ भी इंजेक्षन करें , और इसे दायरे में चिपका दें ताकि आप इसे आसानी से अपने दृश्य में उपयोग कर सकें:
.scope('HomeCtrl', ['$scope', 'principal',
function($scope, principal)
{
$scope.principal = principal;
});
एक तत्व दिखाएं या छिपाएँ:
<div ng-show="principal.isAuthenticated()">
I'm logged in
</div>
<div ng-hide="principal.isAuthenticated()">
I'm not logged in
</div>
आदि, इत्यादि। वैसे भी, आपके उदाहरण ऐप में, आपके पास होम पेज के लिए एक राज्य होगा जो अनधिकृत उपयोगकर्ताओं को छोड़ देगा। उनके पास साइन-इन या साइन-अप स्थिति के लिंक हो सकते हैं, या उन रूपों को उस पेज में बनाया जा सकता है। जो भी आपको सूट करे।
डैशबोर्ड पृष्ठ उन सभी स्थितियों से भिन्न हो सकते हैं जिनमें उपयोगकर्ताओं को लॉग इन करने की आवश्यकता होती है, और कहते हैं कि User
भूमिका सदस्य बनें। हमारे द्वारा चर्चा की गई सभी प्राधिकरण सामग्री वहाँ से प्रवाहित होगी।