Laravel 4多用户认证

7
我正在构建一个Laravel 4应用程序,需要为3种实体类型进行登录身份验证:教练,学生和管理员,每种实体类型都有单独的用户界面。虽然我可以使用像Sentry 2这样的包,并使用具有用户类型的单个DB用户表来实现此目的,但是在潜在的多态DB设计模式和可能发生的问题方面,我感到不安。过去曾处理过以前应用程序中的多态问题,以及当您想要规范化DB结构等时可能会创建的问题。对于每种实体类型都有单独的DB表格似乎是更好的方法。
你如何解决这个设计问题?
Laravel 4 auth基本上使用以下文件:
- Auth.php(facade) - AuthManager.php - AuthServiceProvider.php - Guard.php - auth.php(config) - User.php(eloquent model)
我已经尝试复制这些文件,主要是为了教练实体的独立认证,注册facade和service provider到app.php文件中,并进行必要的更改以使用Coach eloquent model进行身份验证的配置:
- AuthCoach.php(facade) - AuthCoachManager.php - AuthCoachServiceProvider.php - Guard.php - authcoach.php(config) - Coach.php(eloquent model)
我仍在使用标准Laravel 4 auth中的Guard.php,但是如果需要通过创建GuardCoach.php文件来自定义Guard方法以进行教练身份验证,则可以轻松扩展Guard。
如果我要为每种实体类型都有单独的身份验证,你认为这是一个好方法吗?
你是否看到任何潜在问题或知道更好的方法?

我在这里回答了一个类似的问题:https://dev59.com/zWMk5IYBdhLWcg3w_yvn#19139889 不确定是否有帮助... - Xethron
你解决了这个问题吗? - ollieread
2个回答

3
也许我没有很好地理解你的背景,但为什么你不只是使用基于角色的访问控制的基本概念,并对不同的角色呈现不同的内容?如果这还不够严格,您可以使用基于属性的身份验证策略来细分权限。您想要复制(三倍)认证逻辑的原因是什么?更不用说冗余的数据库数据(为不同的用户类型单独设置用户表?恶心!)?
如果您不满意Sentry(就我个人而言,我不使用该库),我可以推荐Zizaco/Confide + Zizaco/Entrust作为用户/角色/权限管理的清晰和优雅的解决方案。在此处查看Zizaco GitHub
一个快速的一般性思路:
- 为整个应用程序使用单一干净的身份验证机制 - 使用角色或角色+权限进行粒度访问控制 - 将管理员逻辑分离到单独的控制器中(AdminUserController、AdminCoachController等) - 我看不出组合适当的刀片模板结构以使其所有都做得很好和组织良好所面临的困难 - 您有哪些多态的问题?
如果您担心您的用户表会变得混乱,请将其用作存储身份验证详细信息的位置,并将所有其他必要(非身份验证)用户详细信息放在另一个表中。
希望这可以帮助您解决问题,即使我只是很好地理解了您的问题。

3
我认为你正在用大锤打蚊子。
以下是我解决同样问题的方法:
- 我想确保每个用户的身份验证(用户名、密码)存储在同一张表中。基本上,我有三种类型的用户。 - 我使用了 Sentry 2,这使得管理身份验证变得轻而易举。 - 使用 Sentry 2 提供的默认迁移,我向“用户”表添加了一个“角色”列,用于区分 3 种用户类型。 - 对于每种用户类型,我创建了一个具有特定字段的表格。 - 当用户通过身份验证时,我会从“用户”表中获取他们的“角色”,运行几个 if 语句,并知道要提供哪个视图。
然后蚊子就完全死了。
至于你的问题:
- 基本上,我们的方法是相同的,因为每种用户类型都有一个单独的表格来存储它们不共享的字段(除了名字、姓氏、电子邮件、密码、最后登录等)。 - 你的方法将允许一个用户属于三个实体 - 这在逻辑上是不正确的。我的方法则不会 - 这在逻辑上是正确的。 - 你担心“多态问题”,但我认为我们在这里没有很多问题需要处理。我们可能只需在我们的模型中定义一个教练,例如,属于一个用户。而一个用户则拥有一个教练。 - 但实际上,我们甚至不需要定义这些关系。因为在身份验证时,我们需要运行 if 语句。所以,使用从身份验证返回的用户对象,我们将知道两件事:要获取用户类型特定信息的表格和要提供给已验证用户的视图。
别害怕,孩子。

在数据库的其余部分中,您将使用哪个ID作为每个用户类型的FK(外键)?是auth表ID还是特定于用户的表ID? - Ben
我会使用用户ID,因为我知道每个用户的ID都是唯一的。如果您使用用户类型ID,则不会是唯一的,因为每种用户类型都有一个单独的表(教练,学生,管理员)。您不必担心这三个表具有外键,因为它们只是补充用户表。用户表是“老板”。 - kJamesy
好的,酷!那么,考虑到两种用户类型都有一个FK user_id,如果你有一个课程表,你将如何记录与哪个教练和学生相关的课程?在这里,一个单一的关系ID也可以起作用,通过拥有一个user_parent_child表(id,parent_id(教练user_id),child_id(学生user_id)),并将user_parent_child_id记录为课程表中的FK。不过这看起来非常混乱。 - Ben
在这种情况下——因为一节课是特定于教练和学生的,你显然需要在课程表中有id|coach_id|student_id等字段。然后,如果你正确地定义了用户/教练和用户/学生关系,要获取带有给定课程上学生信息的课程对象,你只需要像这样做 $lesson = Lesson::with('student.user')->get(); 例如。 - kJamesy
我将使用innoDB表设置FK以保持良好的数据库完整性,在课程表中,coach_id和student_id都将有user_id的FK,这意味着在课程表中不会对user_id类型进行DB验证。教练用户类型可能会记录在student_id中,反之亦然。其他DBMS允许使用FK约束来管理此问题,但据我所知,在MySQL中这非常具有挑战性。随着数据库的增长,这些完整性问题将无处不在,这也回到了我最初关注的一个用户表与用户类型分类的问题。你有什么想法吗? - Ben
这不正确:“课程表中的coach_id和student_id都将有user_id的外键”。实际上,这两个是外键!(课程表有2个外键:coach_id和student_id。)它们将课程表与相应的教练表和学生表相关联。教练表和学生表都将至少有一个外键:user_id,这将使它们与用户表相关联。因此,如果您想获取所有课程+其中的学生,则可以执行以下操作:$lesson = Lesson::with('student.user')->get(); - kJamesy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接