MVC 多用户身份验证/安全
我一直在为一家公司开发一个 Web 应用程序,帮助他们报价、管理库存和运行作业。我们相信该应用程序将对行业中的其他公司有用,但我不想推出该应用程序的单独实例,因此我们将其设为多用户(或多公司可能是一个更好的术语,因为每个公司都有多个用户)。
它是在 Codeigniter 中构建的(希望我在 Rails 中完成了它,但现在已经太晚了),并且我尝试遵循瘦控制器胖模型方法。我只是想确保我正确地完成了授权方面的工作。当用户登录时,我会将 companyID 和 userID 一起存储在会话中。我认为用户界面的每个表都应该有一个额外的companyID字段(通过关系间接访问的表可能也不需要存储companyID,请告诉我我是否错了)。检索数据似乎非常简单,只需在 AR 中添加一个附加 where 子句即可将公司 ID 添加到选择中,例如 $this->db->where('companyID', $companyID)
。我对此没问题。
然而,我想知道的是如何确保用户只能修改自己公司内的数据(如果他们使用 firebug 或类似工具向随机 quoteID 发送删除请求)。我想到的一种方法是将上面相同的 where 子句添加到模型中的每个更新和删除方法中。这在技术上是可行的,但我只是想知道这是否是正确的方法,或者是否有人有任何其他想法。
另一种选择是检查用户的公司在修改之前是否拥有该记录,但这似乎是数据库请求的双重处理,而且我真的不知道这样做是否有任何好处。
我很惊讶我找不到这个问题的答案,我一定是在寻找错误的术语:p。但我将不胜感激有关此主题的任何答案。
预先感谢,
克里斯蒂安
I've been working on a web application for a company that assists them with quoting, managing inventory, and running jobs. We believe the app will be useful to other companies in the industry, but there's no way I want to roll out separate instances of the app, so we're making it multi-user (or multi-company might be a better term, as each company has multiple users).
It's built in Codeigniter (wish I had've done it in Rails, too late now though), and I've tried to follow the skinny-controller fat-model approach. I just want to make sure I do the authorisation side of things properly. When a user logs in I'd store the companyID along with the userID in the session. I'm thinking that every table that the user interfaces with should have an additional companyID
field (tables accessed indirectly via relationships probably wouldn't need to store the companyID too, tell me if I'm wrong though). Retrieving data seems pretty straight forward, just have an additional where clause in AR to add the company ID to the select, eg $this->db->where('companyID', $companyID)
. I'm ok with this.
However, what I'd like to know is how to ensure users can only modify data within their own company (in case they send say, a delete request to a random quoteID, using firebug or a similar tool). One way I thought of is to add the same where clause above to every update and delete method in the models as well. This would technically work, but I just wanted to know whether it's the correct way to go about doing it, or if anyone had any other ideas.
Another option would be to check to see if the user's company owned the record prior to modification, but that seems like a double-up on database requests, and I don't really know if there's any benefit to doing it this way.
I'm surprised I couldn't find an answer to this question, I must be searching for the wrong terms :p. But I would appreciate any answers on this topic.
Thanks in advance,
Christian
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想说你正在以正确的方式处理这件事。将所有项目保留在同一个表中将允许您运行全局统计数据以及本地化统计数据 - 所以我认为这是更好的方法。
我还想说,最好将您提到的
where
子句添加到每个查询中(无论是get
、update
、删除
但是,我不确定您是否想要手动执行所有查询,我建议您覆盖模型中的这些方法以添加相关的where<。这样,当你调用时。
$this->model->get()
,您将自动获取添加到查询中的where->($companyID, $userID)
子句。I'd say you're going about this the correct way. Keeping all of the items in the same tables will allow you to run global statistics as well as localized statistics - so I think this is the better way to go.
I would also say that it would be best to add the
where
clause you mention to each query (whether it's aget
,update
,delete
. However, I'm not sure you'd want to manually go in and do that for all of your queries. I would suggest you overwrite those methods in your models to add the relevantwhere
clauses. That way, when you call$this->model->get()
, you will automatically get thewhere->($companyID, $userID)
clause added to the query.从表面上看,这可能是一个更多 API 类型的系统(否则这只是一个普通的用户身份验证系统)。
简单身份验证
无论如何,我认为 API 的最佳选择是有两个表,
companies
和users
companies
表中有一个companyID
和password
。users
表中将每个用户链接到一个公司。然后,当用户发出请求时,让他们在每个请求中发送
companyID
和password
。oauth
下一个选项实施起来稍微困难一些,意味着另一端也必须设置 Oauth 身份验证,即 oauth。
但是,在我看来,总体来说使用起来更好,而且更安全。
From the looks of things it looks like this might be a more API type system (as otherwise this is simply a normal user authentication system).
Simple Authentication
Anyway, the best bet I can see for an API is to have two tables,
companies
andusers
in the
companies
table have ancompanyID
, andpassword
. in theusers
table link each user to a company.Then when a user makes a request have them send through the
companyID
andpassword
with every request.oauth
The next option, slightly harder to implement, and means that the other end must also setup Oauth authentication is oauth.
But, in my opinion is much nicer overall to use and is a bit more secure.
一种方法是使用表前缀。但是,如果您已经有很多表,复制它们显然会迅速增加数据库的大小。如果您没有很多表,这应该可以扩展。您可以根据用户凭据设置前缀。请参阅本页的前缀部分: http://codeigniter.com/user_guide/database/queries.html 了解有关与他们合作的更多信息。
另一种选择是不推出应用程序的单独实例,而是使用单独的数据库。这是 CI 论坛上讨论多个数据库的帖子: http://codeigniter.com/forums/viewthread/145901 / 在这里,您再次可以根据用户凭据选择正确的数据库。
我看到的唯一其他选项是您提出的选项,其中您向指定所有权的数据添加标识符。这应该可行,但看起来有点可怕。
One way to do it would be with table prefixes. However, if you have a lot of tables already, duplicating them will obviously grow the size of the db rapidly. If you don't have many tables, this should scale. You can set the prefix based on user credentials. See the prefixes section of this page: http://codeigniter.com/user_guide/database/queries.html for more on working with them.
Another option is to not roll out separate instances of the application, but use separate databases. Here is a post on CI forum discussing multiple db's: http://codeigniter.com/forums/viewthread/145901/ Here again you can select the proper db based on user credentials.
The only other option I see is the one you proposed where you add an identifier to the data designating ownership. This should work, but seems kinda scary.