如何根据设计加密密码进行身份验证?(How to authenticate based on devise encrypted password?)

编程入门 行业动态 更新时间:2024-10-14 04:27:48
如何根据设计加密密码进行身份验证?(How to authenticate based on devise encrypted password?)

我有两个使用设计进行身份验证的Rails应用程序:网站和API。 即使我是这两个应用程序的所有者,出于多种原因,我希望两者之间完全分离。 当用户在网站上注册时,会在API端自动创建一个帐户。 我遇到的最大问题是让两个应用程序之间的用户表保持同步。 我最终在网站用户模型上创建了一堆RESTful API回调,用于创建/更新API用户。

第二部分是代表登录网站的用户调用API。 问题是我没有用户的解密密码,所以我可以进行API调用。 所有API调用都使用基本HTTP身份验证。 密码被散列到数据库中,无法解密(这是一件好事,谢谢你的设计)。 因为我保持所有用户列在2个数据库之间同步,所以我的网站用户encrypted_pa​​ssword列与我的API用户encrypted_pa​​ssword列相同。

那么,我有什么选择来解决这个问题? 我正在考虑修改API,以便每个常规调用的管理员调用采用管理员用户名和密码以及用户ID(例如,获取该用户的事务)。 或者,在两个应用程序之间实现共享数据库 - 但我在用户和其他模型之间有很多关联......索引如何工作?! 或者,劫持设计认证并将encrypted_pa​​ssword(从我的网站)与encrypted_pa​​ssword(到我的API)进行比较 - 因为它们完全相同; 但这会打开一个安全的蠕虫病毒。 或者,创建密钥身份验证并为用户生成唯一的GUID ......但这样做与将密码存储在数据库中一样糟糕。 我讨厌所有这些解决方案。 也许有人有更好的主意?

I have two Rails apps using devise for authentication: a website and an API. Even though I'm the owner of these 2 apps, for many reasons, I wanted complete separation between the two. When a user signs up on the website, an account is automatically created on the API side. The biggest problem I have is keeping the users table in sync between the two apps. I ended up with a bunch of RESTful API callbacks on the website user model which create/update the API user.

The second part is calling the API on behalf of the user logged into the website. Problem is that I don't have the user's decrypted password so I can make the API call. All API calls use basic HTTP authentication. The passwords are hashed into the database and cannot be decrypted (which is a good thing, thank you devise). Because I keep all users columns in sync between the 2 databases, my website users encrypted_password column is identical to my API users encrypted_password column.

So, what options do I have for solving this? I'm thinking either modifying the API such that an admin call for each regular call takes an admin username and password and a user ID (to get that user's transactions for example). Or, implement a shared database between the 2 apps - but I have a lot of associations between users and other models... how would indexing even work?! Or, hijack the devise authentication and compare encrypted_password (from my website) to encrypted_password (to my API) - since they are the exact same; but this opens a security can of worms. Or, create keys authentication and generate unique GUIDs for users... but then that would be just as bad as having decrypted password stored in a database. I hate all these solutions. Perhaps someone has a better idea?

最满意答案

当您在Devise中对用户进行身份验证时,它会获取明文密码并将其与胡椒相结合并将其传递给bcrypt。 如果加密的密码与数据库中的值匹配,则返回记录。

胡椒基于你的rails app秘密。 因此,除非两个应用程序具有完全相同的秘密,否则即使您拥有正确的加密密码,身份验证也会失败。 请记住, bcrypt的输入必须相同才能得到相同的结果。 这意味着相同的明文,盐,胡椒和数量的延伸。

你是正确的,来回共享密码不是一个可靠的解决方案。 您也是正确的,因为使用UUID而不是数字自动递增ID是解决方案的一部分。

您可以做的是实现自己的身份验证提供程序。 门卫gem可以很容易地设置您自己的OAuth提供程序(或者如果可以使用外部服务,则可以使用Auth0)。

Web应用程序将使用Devise + OmniAuth根据身份验证提供程序对用户进行身份验证,并使用返回的凭据来识别Web应用程序中的用户。

对于API应用程序,我将使用Knock进行JWT身份验证。 API服务器通过oauth gem代理您的身份验证服务器的位置。

但是,此时您应该考虑您的Web和API应用程序是否真的应该在不同的DB上运行。 保持两个数据库之间的同步写入可能是一项非常重要的任务,你应该问问自己在这个阶段是否真的需要它。

When you authenticate a user in Devise it takes the plaintext password and combines it with a pepper and passes it through bcrypt. If the encypted password matches the value in the DB the record is returned.

The pepper is based on your rails app secret. So unless the two apps have the exact same secret then authentication will fail even if you have the correct encrypted password. Remember that the input to bcrypt has to be identical to give the same result. That means the same plaintext, salt, pepper and number of stretches.

You're correct in that sharing the passwords back and forth is not a solid solution. You are also correct in that using UUIDs instead of a numerical auto-incrementing id is part of the solution.

What you can do is implement your own authentication provider. The Doorkeeper gem makes it pretty easy to setup your own OAuth provider (or you can use Auth0 if using an external service is acceptable).

The web app would use Devise + OmniAuth to authenticate users against the authentication provider and use the credentials returned to identify the user in the web application.

For the API application I would use Knock for JWT authentication. Where the API server proxies to your authentication server via the oauth gem.

However you should consider at this point if your web and API app really should be running on separate DBs. Keeping writes in sync across both DBs can be quite the task and your should ask yourself if your really need it at this stage.

更多推荐

本文发布于:2023-07-14 14:30:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1105107.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:身份验证   密码   authenticate   based   encrypted

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!