[英]AngularJS: Basic example to use authentication in Single Page Application
我是AngularJS的新手並完成了他們的教程,並對它有所了解。
我有一個准備好項目的后端,每個REST
端點都需要進行身份驗證。
我想做的事
a。)我想為我的項目http://myproject.com
創建一個頁面。
b。)一旦用戶點擊瀏覽器中的URL,基於用戶是否登錄,他將在同一網址http://myproject.com
下顯示主頁/視圖或登錄頁面/視圖。
c。)如果用戶未登錄,則填寫表單並且服務器在會話中設置USER_TOKEN
,因此所有對端點的進一步請求將基於USER_TOKEN
進行身份驗證
我的困惑
a。)如何使用AngularJS處理客戶端身份驗證? 我在這里和這里看到但不明白如何使用它們
b。)如何根據用戶是否登錄到同一網址http://myproject.com
向用戶呈現不同的視圖
我第一次使用angular.js,真的很困惑如何開始。 非常感謝任何建議和/或資源。
我創建了一個github repo,基本上總結了這篇文章: https : //medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
我會嘗試盡可能好地解釋,希望我幫助你們中的一些人:
(1)app.js:在app定義上創建認證常量
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)訪問控制:要拒絕某些路由的訪問,必須執行兩個步驟:
a)在ui路由器的$ 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通過添加directives.js中包含的指令,可以輕松避免第1篇文章中所述的表單數據自動填充的錯誤。
PS2用戶可以輕松調整此代碼,以允許查看不同的路徑,或顯示不打算顯示的內容。 邏輯必須在服務器端實現,這只是一種在ng-app上正確顯示內容的方法。
我喜歡這種方法並在服務器端實現它,而不在前端執行任何與身份驗證相關的操作
我最近的應用程序上的'技術'是..客戶端不關心Auth。 應用程序中的每一件事都需要首先登錄,因此除非在會話中檢測到現有用戶,否則服務器始終只提供登錄頁面。 如果找到session.user,則服務器只發送index.html。 巴姆:-o
尋找“安德魯·喬斯林”的評論。
我在這里回答了類似的問題: AngularJS Authentication + RESTful API
我為UserApp編寫了一個AngularJS模塊 ,它支持受保護/公共路由,在登錄/注銷時重新路由,用於狀態檢查的心跳, 將會話令牌存儲在cookie中,事件等。
你可以:
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請求發送它。 在后端,使用UserApp API (如果使用UserApp)檢查令牌是否有效。
如果您需要任何幫助,請告訴我!
在angularjs中,您可以創建UI部件,服務,指令以及表示UI的angularjs的所有部分。 這是一項很好的技術。
任何進入這項技術的人都希望對“用戶”進行身份驗證,那么我建議使用c#web api的強大功能。 為此,您可以使用OAuth規范,該規范將幫助您構建強大的安全機制來對用戶進行身份驗證。 一旦使用OAuth構建WebApi,您需要為令牌調用該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; };
一旦獲得令牌,您就可以在Token的幫助下從angularjs請求資源,並使用OAuth規范訪問在Web Api中保持安全的資源。
請查看以下文章以獲取更多幫助: -
我認為每個JSON響應都應包含一個屬性(例如{authenticated:false}),客戶端必須每次都測試它:如果為false,則Angular控制器/服務將“重定向”到登錄頁面。
如果用戶捕獲de JSON並將bool更改為True會發生什么?
我認為你不應該依賴客戶端來做這些事情。 如果用戶未經過身份驗證,則服務器應該只重定向到登錄/錯誤頁面。
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; };
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.