限制RESTful PHP API中的操作

时间:2015-08-09 05:55:48

标签: php angularjs

我正在创建一个AngularJS应用程序,其中包含用PHP编写的restful API作为后端。这是我第一次“一起”使用AngularJS和PHP。

Angular正在使用ngCookies模块跟踪用户的身份验证。某些操作(如删除内容)应仅适用于具有特定权限的用户。如何确保“普通”用户或未登录的用户无法访问API的删除操作?

任何想法都表示赞赏。

2 个答案:

答案 0 :(得分:1)

我是这样做的。

  1. users数据库表中,我添加了名为token VARCHAR(36)
  2. 的列
  3. 每当用户登录时:
  4. 我更新了lastlogin
  5. 我使用MD5($ip.$email.$logindate)
  6. 更新该令牌
  7. 现在我将用户对象返回给Angular,而angular知道令牌。
  8. 在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
        };
    })
    
  9. 这是我在应用

    中插入的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前端

    https://github.com/Coach-Hub

    这是基本的想法,你当然可以围绕它构建。

答案 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()));
}