0

概括


我有一些复杂的数据库结构,我只想将数据提供给授权成员——他们的角色也取决于存储在数据库中的数据。它一直工作到现在,但现在我想扩展服务,它变得非常复杂。必须有一种优雅的方式。

注意:我没有使用 ASP.NET,所以请不要建议那些与它紧密相关的补救措施,尽管我对授权过程建模的想法持开放态度。

背景


好吧,我之前也问过这个问题,但令我惊讶的是,它并没有得到任何好的回应,所以我在这里用不同的词再次发布它。我正在开发一个 Web 应用程序,并且在如何以优雅的方式对授权过程进行建模时遇到问题。

假设我有一个提供以下服务的应用程序。有“项目”/工作区,您可以在其中发布内容并评论这些帖子。被视为“开放”的项目也可以被“关注” - 因此关注者可以访问内容。为了使这种情况更接近我的实际服务,项目“成员”可以决定追随者可以访问的内容。这可能(或可能不!)看起来很复杂,但实际的应用程序更复杂。我所做的是在 sql 查询本身中填写过滤代码。这是一个代码示例:

    public function getProjectById($id) {
        $auth = new Auth();
        $userid = $auth->getCurrentUserId();


        $sql = "
          SELECT P.id, P.userId, P.name, P.description,
                 P.creationTime, P.startTime, P.endTime, P.isOpen
          FROM       projects P
          INNER JOIN project_members PM
                      ON PM.projectid = P.id
                     AND P.id = '{id}'
                     AND (PM.userId = '{userid}' OR P.isOpen = 1)
        ";

        return $this->result($sql, array( "userid" => $userid, "id" => $id ));
    }

这看起来很糟糕,因为我还必须将此数据提供给项目关注者(此处未显示)。评论和帖子处理代码的复杂性增加了。现在,有没有更好的方法来做到这一点 - 必须有。我应该将授权逻辑分离到其他类吗?或者/我应该在数据库中使用“视图”(完全没有必要,但我仍然想指出它们不是 MVC 视图)?或者还有更好的、不笨拙的方法来解决这个问题吗?

欢迎所有建议 - 即使是那些旨在更改数据库结构的建议 - 尽管我想知道为什么需要这样做。

提前致谢!

4

1 回答 1

1

我认为您在视图方面处于正确的轨道上,但由于每次调用都需要传递用户 ID,听起来您真正需要的是表值函数。我最熟悉 Microsoft SQL,它看起来像这样:

SELECT P.*
FROM Projects AS P
     INNER JOIN dbo.AuthProjects(@UserID) AS AP ON P.ProjectID = AP.ProjectID

请注意,TVF 从字面上返回一个表,您可以加入该表以查看哪些项目可用。TVF 定义可能如下所示:

CREATE FUNCTION dbo.AuthProjects(@UserID INT)
    RETURNS @Results TABLE (ProjectID INT NOT NULL, WriteAccess BIT NOT NULL)
AS BEGIN
    INSERT INTO @Results (ProjectID, WriteAccess)
        SELECT
            ProjectID, WriteAccess
        FROM
            Authorizations
        WHERE
            UserID = @UserID

    -- Additional logic for more ways a project may be authorized

    RETURN
END
于 2012-04-26T19:55:48.673 回答