我正在寻找最好的建筑解决方案。
我有以下html:
<body ng-controller="individualFootprintController as $ctrl">
<div ng-hide="$ctrl.authenticated">
<h1>Login</h1>
With Corporate Account: <a href="/login/corporate">click here</a>
</div>
和控制器:
function individualFootprintController($http) {
var self = this;
$http.get("/is_auth").success(function () {
self.authenticated = true;
})
.error(function() {
self.authenticated = false;
}
);
}
问题:
1)此控制器是否适合具有此逻辑?
2)我想拥有实际的“is_authenticated”值。如果我只想发一次请求
,如何才能实现这一点答案 0 :(得分:0)
据推测,使用后端进行身份验证需要某种实际的令牌。即您不只是在某处设置true
/ false
标志并将其称为身份验证,但为了能够与后端通信,您需要在请求中包含用户名/密码/ cookie /令牌或请求将被拒绝。
控制器是存放此类东西的不好的地方,因为控制器不是永久性的。或者至少你不应该尽可能使它们永久化。此外,将令牌存储在控制器中不允许任何其他访问它。
应该如何构建的粗略草图:
app.service('AuthService', function () {
this.token = null;
});
app.service('FooService', function (AuthService, $http) {
$http.get(..., AuthService.token, ...)
});
app.controller('LoginStatusController', function (AuthService) {
Object.defineProperty(this, 'isLoggedIn', {
get: function () { return AuthService.token != null; }
});
});
<div ng-controller="LoginStatusController as ctrl">
<div ng-hide="ctrl.isLoggedIn">
当您实际登录并获取令牌时,您设置AuthService.token
并且它将可供所有其他服务和控制器使用。如果令牌变为无效或未设置,则所有服务和控制器都将失去其身份验证状态。
答案 1 :(得分:0)
我通常做的是以下内容:
使用 ui-router
利用resolve
挂钩(解析一些args并将它们注入控制器),并将我的路由定义为主要路由的子路由,检查每次路由更改时的身份验证
<强>脚本/服务/ user.js的强>
angular.module('yourmodule')
.service('userSrv', function ($http, $q) {
var srv = {};
srv.getAuthenticatedUser = function() {
return $http.get("/authenticated_user");
};
return srv;
});
<强>脚本/ routes.js 强>
angular
.module('yourmodule')
.config(function ($stateProvider) {
$stateProvider
.state('authenticated', {
abstract: true,
template: '<ui-view />',
controller: 'AuthenticatedCtrl',
resolve: {
signedInUser: function(userSrv, $q) {
return userSrv.getAuthenticatedUser()
.then(function(null, function() {
//Catch any auth error, likely 403
//And transform it to null "signedInUser"
//This is the place to handle error (log, display flash)
return $q.resolve(null);
});
}
}
})
.state('authenticated.myspace', {
url: '/myspace',
templateUrl: 'views/myspace.html'
});
});
利用视图中的$ scope继承
<强>脚本/控制器/ authenticated.js 强>
angular.module('yourmodule')
.controller('AuthenticatedCtrl', function (signedInUser, $scope, $state) {
//Here you set current user to the scope
$scope.signedInUser= signedInUser;
$scope.logout = function() {
//this is where you would put your logout code.
//$state.go('login');
};
});
<强>视图/ myspace.html 强>
<!-- here you call parent state controller $scope property -->
<div ng-hide="signedInUser">
<h1>Login</h1>
With Corporate Account: <a href="/login/corporate">click here</a>
</div>
1)我想要实际的&#34; is_authenticated&#34;值。如果我只想触发一次请求,怎么能实现这一点 我的解决方案在每次路由更改时要求经过身份验证的用户。这看起来很奇怪,但这实际上是可行且快速的。查询不应该是&gt; 30ms它是引擎盖下的一个非常小的选择。那么,问我&#34;我是否经过身份验证&#34;和#34;获得经过身份验证的用户&#34;是一回事,除了一个返回一个布尔值,另一个返回用户。我建议,就像我告诉你的那样,处理&#34;我是否经过身份验证&#34;通过请求经过身份验证的用户提出问题,然后使用&#34; if(user)&#34; (空值处理)。
2)这个控制器是否适合拥有这个逻辑? 是的,不是。正如您所看到的,控制器是将用户设置为范围事物的地方,但是范围继承允许您不为每个路径重复它。虽然,http api逻辑应移植到服务,并且路由事件(&#34;获取此页面的经过身份验证的用户,请&#34;是路由事件IMHO)应该设置在单独的文件中。
注意:如果您需要完整的路线&#34;保护&#34; (比如在未经过身份验证时重定向,请提出另一个问题,我很乐意回答)