Ruby 最先进的身份验证框架
= Rodauth
Rodauth is Ruby's most advanced authentication framework, designed to work in any rack application. It's built using Roda and Sequel, but it can be used with other web frameworks, database libraries, and databases.
When used with PostgreSQL, MySQL, and Microsoft SQL Server in the default configuration, it offers additional security for password hashes by protecting access via database functions.
Rodauth supports multiple multifactor authentication methods, multiple passwordless authentication methods, and offers both an HTML and JSON API for all supported features.
== Design Goals
=== Feature Documentation
The options/methods for the supported features are listed on a separate page per feature. If these links are not active, please view the appropriate file in the doc directory.
== Resources
Website :: http://rodauth.jeremyevans.net Demo Site :: http://rodauth-demo.jeremyevans.net Source :: http://github.com/jeremyevans/rodauth Bugs :: http://github.com/jeremyevans/rodauth/issues Discussion Forum (GitHub Discussions) :: https://github.com/jeremyevans/rodauth/discussions Alternate Discussion Forum (Google Groups) :: https://groups.google.com/forum/#!forum/rodauth
== Dependencies
There are some dependencies that Rodauth uses depending on the features in use. These are development dependencies instead of runtime dependencies in the gem as it is possible to run without them:
tilt :: Used by all features unless in JSON API only mode or using :render=>false plugin option. rack_csrf :: Used for CSRF support if the csrf: :rack_csrf plugin option is given (the default is to use Roda's route_csrf plugin, as that allows for more secure request-specific tokens). bcrypt :: Used by default for password hashing, can be skipped if password_match? is overridden for custom authentication. argon2 :: Used by the argon2 feature as alternative to bcrypt for password hashing. mail :: Used by default for mailing in the reset_password, verify_account, verify_login_change, change_password_notify, lockout, and email_auth features. rotp :: Used by the otp feature rqrcode :: Used by the otp feature jwt :: Used by the jwt feature webauthn :: Used by the webauthn feature
You can use gem install --development rodauth to install the development dependencies in order to run tests.
== Security
=== Password Hash Access Via Database Functions
By default on PostgreSQL, MySQL, and Microsoft SQL Server, Rodauth uses database functions to access password hashes, with the user running the application unable to get direct access to password hashes. This reduces the risk of an attacker being able to access password hashes and use them to attack other sites.
The rest of this section describes this feature in more detail, but note that Rodauth does not require this feature be used and works correctly without it. There may be cases where you cannot use this feature, such as when using a different database or when you do not have full control over the database you are using.
Passwords are hashed using bcrypt by default, and the password hashes are kept in a separate table from the accounts table, with a foreign key referencing the accounts table. Two database functions are added, one to retrieve the salt for a password, and the other to check if a given password hash matches the password hash for the user.
Two database accounts are used. The first is the account that the application uses, which is referred to as the +app+ account. The +app+ account does not have access to read the password hashes. The other account handles password hashes and is referred to as the +ph+ account. The +ph+ account sets up the database functions that can retrieve the salt for a given account's password, and check if a password hash matches for a given account. The +ph+ account sets these functions up so that the +app+ account can execute the functions using the +ph+ account's permissions. This allows the +app+ account to check passwords without having access to read password hashes.
While the +app+ account is not be able to read password hashes, it is still be able to insert password hashes, update passwords hashes, and delete password hashes, so the additional security is not that painful.
By disallowing the +app+ account access to the password hashes, it is much more difficult for an attacker to access the password hashes, even if they are able to exploit an SQL injection or remote code execution vulnerability in the application.
The reason for extra security in regards to password hashes stems from the fact that people tend to choose poor passwords and reuse passwords, so a compromise of one database containing password hashes can result in account access on other sites, making password hash storage of critical importance even if the other data stored is not that important.
If you are storing other sensitive information in your database, you should consider using a similar approach in other areas (or all areas) of your application.
=== Tokens
Account verification, password resets, email auth, verify login change, remember, and lockout tokens all use a similar approach. They all provide a token, in the format "account-id_long-random-string". By including the id of the account in the token, an attacker can only attempt to bruteforce the token for a single account, instead of being able to bruteforce tokens for all accounts at once (which would be possible if the token was just a random string).
Additionally, all comparisons of tokens use a timing-safe comparison function to reduce the risk of timing attacks.
=== User Enumeration
Rodauth does not attempt to prevent user enumeration. Trying to prevent user enumeration is generally futile (defeated using timing attacks) and significantly harms the user experience (e.g. "no matching login" vs "login or password is incorrect" error messages). Additionally, as soon as you support user-specific login methods (e.g. accepting password or email auth), you must allow user enumeration.
If you think you need to prevent user enumeration, reconsider. If you are sure you need to prevent user enumeration, you would be better off using an authentication library designed to prevent user enumeration, instead of using Rodauth and trying to layer user enumeration prevention on top of it.
=== Caching
Rodauth is designed to avoid database queries for every request to check authentication state by caching information in the session. However, this means that changes to the state of the account outside of the current session are not reflected in the session. For example, if an account has multiple sessions open, and one session closes the account, the other session remains open by default. If you want to have all requests check the account state, and are willing to accept a database query in every request to do so, you should use the active_sessions feature.
== Sessions
Rodauth is designed to support any valid Rack session implementation, but to clear sessions, it either calls +clear_session+ on the Roda scope (implemented by the Roda sessions plugin), or +session.clear+ otherwise. For some session implementations, such as those based on Rack::Session::Abstract::Persisted, +session.clear+ is insufficient to prevent session fixation. If you aren't using Roda's sessions plugin, Rack::Session::Cookie, or rodauth-rails, consult the documentation for your session implementation to determine how to prevent session fixation when clearing the session. For Rack::Session::Abstract::Persisted, you can do:
clear_session do session.options[:renew] = true session.clear end
== HMAC
You are strongly encouraged to use the +hmac_secret+ configuration method to set an HMAC secret. Setting an HMAC secret will enable HMACs for additional security, as described below. If you are sure you do not want to use HMACs, you can set hmac_secret nil, but be aware that this reduces Rodauth's security.
=== email_base feature
All features that send email use this feature. Setting +hmac_secret+ will make the tokens sent via email use an HMAC, while the raw token stored in the database will not use an HMAC. This will make it so if the tokens in the database are leaked (e.g. via an SQL injection vulnerability), they will not be usable without also having access to the +hmac_secret+. Without an HMAC, the raw token is sent in the email, and if the tokens in the database are leaked, they will be usable.
To allow for an graceful transition, you can set +allow_raw_email_token?+ to true temporarily. This will allow the ra
暂无开放 Issues,或尚未同步最近议题。