Surely, if you work with rails, many of your apps use some user authentication frameworks like Devise,, Sorcery, Clearance, or Authlogic. What these frameworks have in common is that they are built on top of Rails. In addition to the good points of rails, they also inherit some limitations such as the bulky model, the abuse of Active Record. One significant option is to use Rodauth. Unlike other frameworks built on rails and Active Record, Rodauth is built on two gems, Roda and Sequel.
Authentication logic is closed
With Rodauth, all user authentication behavior is closure within a Rodauth :: Auth object created inside the Roda middleware and has access to requests.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">class</span> <span class="token class-name">RodauthMiddleware</span> <span class="token operator"><</span> <span class="token constant">Roda</span> <span class="token comment"># define your Rodauth configuration</span> plugin <span class="token symbol">:rodauth</span> <span class="token keyword">do</span> <span class="token comment"># load authentication features you need</span> enable <span class="token symbol">:login</span> <span class="token punctuation">,</span> <span class="token symbol">:logout</span> <span class="token punctuation">,</span> <span class="token symbol">:create_account</span> <span class="token punctuation">,</span> <span class="token symbol">:verify_account</span> <span class="token punctuation">,</span> <span class="token symbol">:reset_password</span> <span class="token comment"># change default settings</span> password_minimum_lenth <span class="token number">8</span> login_return_to_requested_location <span class="token operator">?</span> <span class="token boolean">true</span> reset_password_autologin <span class="token operator">?</span> <span class="token boolean">true</span> logout_redirect <span class="token string">"/"</span> <span class="token comment"># ...</span> <span class="token keyword">end</span> <span class="token comment"># handles requests before they reach the main app</span> route <span class="token keyword">do</span> <span class="token operator">|</span> r <span class="token operator">|</span> <span class="token comment"># handle Rodauth paths (/login, /create-account, /reset-password, ...)</span> r <span class="token punctuation">.</span> rodauth <span class="token comment"># require authentication for certain routes</span> <span class="token keyword">if</span> r <span class="token punctuation">.</span> path <span class="token punctuation">.</span> start_with <span class="token operator">?</span> <span class="token punctuation">(</span> <span class="token string">"/dashboard"</span> <span class="token punctuation">)</span> rodauth <span class="token punctuation">.</span> require_authentication <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
When we add the above Roda app to the middleware stack, the route block will be called with each request before it reaches the main app. R.rodauth will handle the routes, rodauth.require_authentication will redirect to the login page if the user is not already logged in. At the end of the block, the request will be routed to the main app. Rodauth instances will still exist in the controller and view, so you can request authentication in the controller if you want to:
1 2 3 4 5 | <span class="token keyword">class</span> <span class="token class-name">PostsController</span> <span class="token operator"><</span> <span class="token constant">ApplicationController</span> before_action <span class="token operator">-</span> <span class="token operator">></span> <span class="token punctuation">{</span> rodauth <span class="token punctuation">.</span> require_authentication <span class="token punctuation">}</span> <span class="token comment"># ...</span> <span class="token keyword">end</span> |
Or render the validation link in the view:
1 2 3 4 5 6 7 | <span class="token operator"><</span> <span class="token operator">%</span> <span class="token keyword">if</span> rodauth <span class="token punctuation">.</span> authenticated <span class="token operator">?</span> <span class="token string">%> <%= link_to "Sign out", rodauth.logout_path, method: :post %></span> <span class="token operator"><</span> <span class="token operator">%</span> <span class="token keyword">else</span> <span class="token string">%> <%= link_to "Sign in", rodauth.login_path %></span> <span class="token operator"><</span> <span class="token operator">%</span> <span class="token operator">=</span> link_to <span class="token string">"Sign up"</span> <span class="token punctuation">,</span> rodauth <span class="token punctuation">.</span> create_account_path <span class="token string">%> <% end %></span> |
Some main functions
Rdauth has all the main functions of an authentication framework:
- Login / logout, remember password.
- Create an account with email authentication.
- Change password, reset password.
- Change email with email authentication.
- Lock or cancel your account.
You will also find that Rodauth includes professional security features like:
- Set an expiry date for a password, not to reuse old passwords.
- Check the complexity of passwords, do not use sketchy passwords.
- Set an expiry for your account and login session.
Some of the other features:
- Authenticate over HTTP
- Authenticate via email
- Log in login
- …
Uniform configuration DSL
For Devise, there are several other layers where you can customize the authentication: global settings, model settings, controller settings and routing settings. Some of the settings above are dynamically customizable (based on the state of the model or controller), while the rest can only be hard-customized. And some Hooks are enabled on the model, while others must be overridden by the controller. As for Rodauth, it provides a uniform DSL customization that changes almost every authentication behavior declared in the Rodauth :: Auth class. You can override a custom method by creating a static value, or passing a dynamic block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">class</span> <span class="token class-name">RodauthApp</span> <span class="token operator"><</span> <span class="token constant">Roda</span> plugin <span class="token symbol">:rodauth</span> <span class="token keyword">do</span> <span class="token comment"># each feature adds its own set of configuration methods</span> enable <span class="token symbol">:login</span> <span class="token punctuation">,</span> <span class="token symbol">:create_account</span> <span class="token punctuation">,</span> <span class="token symbol">:verify_account_grace_period</span> <span class="token punctuation">,</span> <span class="token symbol">:reset_password</span> <span class="token comment"># examples of static values:</span> login_redirect <span class="token string">"/dashboard"</span> <span class="token comment"># redirect to /dashboard after logging in</span> verify_account_grace_period <span class="token number">3.</span> days <span class="token comment"># allow unverified access for 3 days after registration</span> reset_password_autologin <span class="token operator">?</span> <span class="token boolean">true</span> <span class="token comment"># automatically log the user in after password reset</span> <span class="token comment"># examples of dynamic blocks:</span> password_minimum_length <span class="token punctuation">{</span> <span class="token constant">MyConfig</span> <span class="token punctuation">.</span> get <span class="token punctuation">(</span> <span class="token symbol">:min_password_length</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># change minimum allowed password length</span> login_valid_email <span class="token operator">?</span> <span class="token punctuation">{</span> <span class="token operator">|</span> login <span class="token operator">|</span> <span class="token constant">TrueMail</span> <span class="token punctuation">.</span> valid <span class="token operator">?</span> <span class="token punctuation">(</span> login <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># override email validation logic</span> verify_account_redirect <span class="token punctuation">{</span> login_redirect <span class="token punctuation">}</span> <span class="token comment"># after account verification redirect to wherever login redirects to</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
Rodauth provides a DSL for developing new features, which streamlines adding new custom methods and creates the most flexible authentication behaviors possible.
Some other features
Exploited authentication features
Rodauth has done a great job at making the authentication features independent. Each feature is contained in a single file, the code is only loaded when the feature is activated. This makes it easy to learn the features.
1 2 3 4 5 6 7 8 9 10 11 | enable <span class="token symbol">:create_account</span> <span class="token punctuation">,</span> <span class="token comment"># create account and automatically login -- lib/features/rodauth/create_account.rb</span> <span class="token symbol">:verify_account</span> <span class="token punctuation">,</span> <span class="token comment"># require email verification after account creation -- lib/features/rodauth/verify_account.rb</span> <span class="token symbol">:verify_account_grace_period</span> <span class="token punctuation">,</span> <span class="token comment"># allow unverified login for a certain period of time -- lib/features/rodauth/verify_account_grace_period.rb</span> <span class="token symbol">:change_login</span> <span class="token punctuation">,</span> <span class="token comment"># change email immediately -- lib/features/rodauth/change_login.rb</span> <span class="token symbol">:verify_login_change</span> <span class="token punctuation">,</span> <span class="token comment"># require email verification before change is applied -- lib/features/rodauth/verify_login_change.rb</span> <span class="token symbol">:password_complexity</span> <span class="token punctuation">,</span> <span class="token comment"># add password complexity requirements -- lib/features/rodauth/password_complexity.rb</span> <span class="token symbol">:disallow_common_passwords</span> <span class="token punctuation">,</span> <span class="token comment"># don't allow using a weak common password -- lib/features/rodauth/disallow_common_passwords.rb</span> <span class="token symbol">:disallow_password_reuse</span> <span class="token punctuation">,</span> <span class="token comment"># don't allow using a previously used password -- lib/features/rodauth/disallow_password_reuse.rb</span> |
Each feature has a database table
Rodauth features are decoupled not only in code, but also in the database. Instead of adding all columns to a single table, in Rodauth each feature has a dedicated table. This makes it more transparent which database columns belong to which features. Rodauth’s features are independent not only in code but also in the database, instead of adding columns in a table, each Rodauth feature has its own table. This helps to distinguish clearly which columns, which database tables belong to which features.
1 2 3 4 5 6 7 | create_table <span class="token symbol">:accounts</span> <span class="token keyword">do</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">end</span> <span class="token comment"># used by base feature</span> create_table <span class="token symbol">:account_password_reset_keys</span> <span class="token keyword">do</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">end</span> <span class="token comment"># used by reset_password feature</span> create_table <span class="token symbol">:account_verification_keys</span> <span class="token keyword">do</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">end</span> <span class="token comment"># used by verify_account feature</span> create_table <span class="token symbol">:account_login_change_keys</span> <span class="token keyword">do</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">end</span> <span class="token comment"># used by verify_login_change feature</span> create_table <span class="token symbol">:account_remember_keys</span> <span class="token keyword">do</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">end</span> <span class="token comment"># used by remember feature</span> <span class="token comment"># ...</span> |
Conclude
Rodauth is one of the frameworks that brings freshness to Ruby programming, offering advanced and easy-to-understand designs of features, backed by powerful customization with DSL for flexibility. high for the framework.