AngularJS:在单页面应用程序中使用身份validation的基本示例
我是AngularJS的新手,并通过他们的教程,并有一个感觉。
我为我的项目准备了一个后端,每个REST
端点都需要进行身份validation。
我想做的事
a。)我想为我的项目http://myproject.com
有一个单独的页面。
b。)一旦用户点击浏览器中的URL,根据用户是否login,他会在同一个urlhttp://myproject.com
下出现主页/视图或login页面/视图。
c。)如果用户没有login,则填写表单,并且服务器在会话中设置USER_TOKEN
,所有对端点的进一步请求将基于USER_TOKEN
我的困惑
a。)如何使用AngularJS处理客户端身份validation? 我在这里和这里看到,但不明白如何使用它们
b。)如何根据用户是否login或不在同一urlhttp://myproject.com
向用户展示不同的视图
我第一次使用angular.js,真的很困惑如何开始。 任何build议和/或资源非常感谢。
我创build了一个github回购总结这篇文章基本上: https : //medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
ng-login Github回购
Plunker
我会尽力解释,希望我能帮你们中的一些人:
(1)app.js:在应用程序定义上创buildauthentication常量
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)authentication服务:以下所有function都在auth.js服务中实现。 $ http服务用于与服务器进行通信以进行authentication过程。 还包含授权function,即允许用户执行特定操作。
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)家长控制器:将其视为应用程序的“主要”function,所有控制器都从此控制器inheritance,并且是此应用程序的身份validation的主干。
<body ng-controller="ParentController"> [...] </body>
(5)访问控制:拒绝某些路线的访问必须执行两个步骤:
a)在ui路由器的$ stateProvider服务中添加允许访问每个路由的angular色的数据,如下所示(同样可以用于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')上添加防止状态改变的function,如果用户没有被授权的话。
$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请求之后,这个拦截器检查状态码,如果下面的一个返回,那么它会广播一个事件来强制用户重新login。
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上正确显示的东西。
我喜欢这个方法,并且在服务器端实现它,而不需要在前端做任何authentication相关的事情
我的最新应用程序的'技术'是…客户端不关心authentication。 应用程序中的每一件事情都需要首先login,所以服务器总是提供login页面,除非在会话中检测到现有用户。 如果findsession.user,服务器只发送index.html。 Bam:-o
请看“Andrew Joslin”的评论。
我就这个问题做了一个快速的截屏。 使您了解如何在您的SPA中实施身份validation系统并将其连接到您的API。 https://www.youtube.com/watch?v=ZHMVP5aLAPM
我在这里回答了一个类似的问题: AngularJS Authentication + RESTful API
我已经为UserApp编写了一个AngularJS模块 ,它支持保护/公共路由,在login/注销时重新路由,检查状态的心跳, 将会话令牌存储在cookie中,事件等。
你可以:
- 修改模块并将其附加到您自己的API或
- 与UserApp (基于云的用户pipe理API)一起使用模块
https://github.com/userapp-io/userapp-angular
如果使用UserApp,则不必为用户编写任何服务器端代码(而不仅仅是validation令牌)。 参加Codecademy的课程试用一下。
下面是一些如何工作的例子:
-
如何指定哪些路由应该公开,哪些路由是login表单:
$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()
路由应该设置为您希望用户在login后redirect的位置。 例:$routeProvider.otherwise({redirectTo: '/home'});
-
具有error handling的login表单:
<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>
-
registry单与error handling:
<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>
(结束会话并redirect到login路由)
-
访问用户属性:
用户属性是使用
user
服务访问的,例如:user.current.email
或者在模板中:
<span>{{ user.email }}</span>
-
隐藏仅在login时才可见的元素:
<div ng-show="user.authorized">Welcome {{ user.first_name }}!</div>
-
根据权限显示一个元素:
<div ua-has-permission="admin">You are an admin</div>
为了validation您的后端服务,只需使用user.token()
获取会话令牌并通过AJAX请求发送。 在后端,使用UserApp API (如果您使用UserApp)检查令牌是否有效。
如果您需要帮助,请告诉我!
在angularjs中,您可以创buildUI部件,服务,指令以及代表UI的所有angularjs部分。 这是很好的技术工作。
就像任何一个刚刚进入这个技术领域并且想authentication“用户”的人一样,那么我build议用c#web api的力量去做。 为此,您可以使用OAuth规范来帮助您构build一个强大的安全机制来对用户进行身份validation。 一旦你用OAuth构buildWebApi,你需要调用这个API来获取token:
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; };
我认为每个JSON响应都应该包含一个属性(例如{authenticated:false}),并且客户端必须每次testing它:如果为false,那么Angular控制器/服务将“redirect”到login页面。
如果用户抓住JSON并将bool更改为True,会发生什么?
我认为你不应该依靠客户端做这些东西。 如果用户没有通过身份validation,服务器应该redirect到login/错误页面。
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; };