我正在创建一个AngularJS应用程序,其中包含用PHP编写的restful API作为后端。这是我第一次“一起”使用AngularJS和PHP。
Angular正在使用ngCookies模块跟踪用户的身份验证。某些操作(如删除内容)应仅适用于具有特定权限的用户。如何确保“普通”用户或未登录的用户无法访问API的删除操作?
任何想法都表示赞赏。
答案 0 :(得分:1)
我是这样做的。
users
数据库表中,我添加了名为token VARCHAR(36)
lastlogin
列MD5($ip.$email.$logindate)
在Angular $http
服务中,我添加了拦截器,在发出任何请求之前Authentication
设置了标头。我使用基本身份验证。我创建了字符串$user_id.'::'.$token
。
app.factory('authInterceptor', function($rootScope, $q, appConfig, $injector, $cacheFactory) {
function request(config) {
if(angular.isDefined($rootScope.currentUser.id)) {
config.headers.Authorization = 'Basic ' +
window.btoa($rootScope.currentUser.id + ':' +
$rootScope.currentUser.token);
}
return config;
}
function response(response) {
if(angular.isDefined(response.data.code) && parseInt(response.data.code) == 401) {
var UserApi = $injector.get('UserApi');
UserApi.logout();
$cacheFactory.get('$http').removeAll();
UserApi.login(response.data.message)
.catch(function() {
var $state = $injector.get('$state');
$state.go('app.home');
});
}
return response || $q.when(response);
}
return {
request: request,
response: response
};
})
这是我在应用
中插入的authInterceptor
工厂
app.config(function($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
})
如果用户获得授权,我会为每个请求设置标准Authentication
标头。
然后在PHP中我得到这个标题。我分别获得用户ID和令牌。然后我使用用户ID从DB获取用户数据,其中我有令牌和上次登录日期。
现在我可以比较令牌并查看该用户是否是登录的用户。
但这不是绝对安全的。如果有人获得此令牌,那么他可以登录。这就是使用IP的原因。不仅我在DB中检查令牌,我还检查IP。我创建MD5($ip.$email.$logindate)
因为我知道所有数据并检查我从角度获得的令牌。如果它是从不同的IP发送的,它将无法通过。
您还可以在authInterceptor
中查看功能响应。每当我遇到身份验证问题时,我都会发回HTTP代码401
。现在回应我知道身份验证失败了。我注销用户并将他重定向到该网站的主页。
现在编码非常简单。您只需返回必须返回的内容,而不关心没有经过身份验证的用户。
但还有更多。如果您需要某种ACL,那么您可以根据需要进行设计。在返回特定RESTFull API方法的类中,您可以定义$acl
属性并设置组的名称。在检查身份验证的位置,您也可以检查ACL。
请在此处查看我的代码,它是PHP后端和Angular前端
这是基本的想法,你当然可以围绕它构建。
答案 1 :(得分:-1)
我不是php开发人员。你不能在前端确保这个东西。下面是我们在NodeJs app中使用的示例代码,用于验证用户是否具有删除的有效权限。
router.patch('/:id', auth.hasRole(userEnums.roles.admin), controller.update);
router.post('/create', auth.hasRole(userEnums.roles.admin), controller.create);
//Checks if the user role meets the minimum requirements of the route
function hasRole(roleRequired) {
if (!roleRequired) throw new Error('Required role needs to be set');
return compose()
.use(isAuthenticated())
.use(function meetsRequirements(req, res, next) {
if (req.user.role.indexOf(roleRequired) !== -1) {
next();
}
else {
res.send(403);
}
});
}
这里 auth.hasRole 是简单的方法/中间件,这是一种咖喱设计模式。它检查use req并检查用户是否具有有效的删除权限。如果用户没有管理员权限,则返回unautherize错误消息。 这适用于管理员和用户关系。我们还在最后使用另一种策略来验证用户。假设我们公开了删除API,任何人都可以删除它。在这种情况下,我们必须确保活动用户必须是文档的所有者。在这种情况下,首先我们获取文档的所有者ID,并将其与请求的用户ID匹配。如果匹配,则删除文档。
BlogPostApiService.destroy(id, _.curry(hasPermission)(req.user))
//hasPermission implementation
function hasPermission(user, blogPost) {
return user && (user.hasRole(UserEnums.roles.admin) || (user._id.toString() == blogPost.author.id.toString()));
}