{"id":13427660,"url":"https://github.com/thoughtbot/clearance","last_synced_at":"2025-10-08T17:13:16.011Z","repository":{"id":435227,"uuid":"56125","full_name":"thoughtbot/clearance","owner":"thoughtbot","description":"Rails authentication with email \u0026 password.","archived":false,"fork":false,"pushed_at":"2025-09-26T21:06:02.000Z","size":6841,"stargazers_count":3735,"open_issues_count":36,"forks_count":467,"subscribers_count":67,"default_branch":"main","last_synced_at":"2025-10-06T20:45:50.797Z","etag":null,"topics":["clearance","rails","rails-authentication","ruby","rubygem","thoughtbot"],"latest_commit_sha":null,"homepage":"https://thoughtbot.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thoughtbot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"thoughtbot"}},"created_at":"2008-09-24T19:57:58.000Z","updated_at":"2025-10-03T13:03:35.000Z","dependencies_parsed_at":"2024-01-30T23:30:21.943Z","dependency_job_id":"2e72c391-4acf-428f-8547-799aec317f8c","html_url":"https://github.com/thoughtbot/clearance","commit_stats":{"total_commits":1596,"total_committers":209,"mean_commits":7.636363636363637,"dds":0.7474937343358397,"last_synced_commit":"17654b88c16aa25af1c6d007775497ddd642f01c"},"previous_names":[],"tags_count":121,"template":false,"template_full_name":null,"purl":"pkg:github/thoughtbot/clearance","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclearance","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclearance/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclearance/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclearance/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thoughtbot","download_url":"https://codeload.github.com/thoughtbot/clearance/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclearance/sbom","scorecard":{"id":883066,"data":{"date":"2025-08-11","repo":{"name":"github.com/thoughtbot/clearance","commit":"6b3dfef9d4cd318cc761c7e6040d79620e4658a9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Code-Review","score":6,"reason":"Found 15/24 approved changesets -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":2,"reason":"3 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/dynamic-readme.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/thoughtbot/clearance/dynamic-readme.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/dynamic-security.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/thoughtbot/clearance/dynamic-security.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/thoughtbot/clearance/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/thoughtbot/clearance/tests.yml/main?enable=pin","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/dynamic-readme.yml:14","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/dynamic-security.yml:14","Warn: no topLevel permission defined: .github/workflows/dynamic-readme.yml:1","Warn: no topLevel permission defined: .github/workflows/dynamic-security.yml:1","Warn: no topLevel permission defined: .github/workflows/tests.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"16 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-h47h-mwp9-c6q6","Warn: Project is vulnerable to: GHSA-vfg9-r3fq-jvx4","Warn: Project is vulnerable to: GHSA-vfm5-rmrh-j26v","Warn: Project is vulnerable to: GHSA-x76w-6vjr-8xgj","Warn: Project is vulnerable to: GHSA-76r7-hhxj-r776","Warn: Project is vulnerable to: GHSA-j3g3-5qv5-52mj","Warn: Project is vulnerable to: GHSA-353f-x4gh-cqq8","Warn: Project is vulnerable to: GHSA-5w6v-399v-w3cc","Warn: Project is vulnerable to: GHSA-47m2-26rw-j2jw","Warn: Project is vulnerable to: GHSA-7g2v-jj9q-g3rg","Warn: Project is vulnerable to: GHSA-7wqh-767x-r66v","Warn: Project is vulnerable to: GHSA-8cgq-6mh2-7j6v","Warn: Project is vulnerable to: GHSA-gjh7-p2fx-99vx","Warn: Project is vulnerable to: GHSA-9j94-67jr-4cqj","Warn: Project is vulnerable to: GHSA-6f62-3596-g6w7","Warn: Project is vulnerable to: GHSA-r995-q44h-hr64"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T08:57:47.895Z","repository_id":435227,"created_at":"2025-08-24T08:57:47.895Z","updated_at":"2025-08-24T08:57:47.895Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278778962,"owners_count":26044256,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clearance","rails","rails-authentication","ruby","rubygem","thoughtbot"],"created_at":"2024-07-31T01:00:36.271Z","updated_at":"2025-10-08T17:13:16.005Z","avatar_url":"https://github.com/thoughtbot.png","language":"Ruby","readme":"# Clearance\n\n[![Build Status](https://github.com/thoughtbot/clearance/actions/workflows/tests.yml/badge.svg)]( https://github.com/thoughtbot/clearance/actions/workflows/tests.yml?query=branch%3Amain)\n[![Code Climate](https://codeclimate.com/github/thoughtbot/clearance.svg)](https://codeclimate.com/github/thoughtbot/clearance)\n[![Documentation Quality](https://inch-ci.org/github/thoughtbot/clearance.svg?branch=main)](https://inch-ci.org/github/thoughtbot/clearance)\n\nRails authentication with email \u0026 password.\n\nClearance is intended to be small, simple, and well-tested. It has opinionated\ndefaults but is intended to be easy to override.\n\nPlease use [GitHub Issues] to report bugs. If you have a question about the\nlibrary, please use the `clearance` tag on [Stack Overflow]. This tag is\nmonitored by contributors.\n\n[GitHub Issues]: https://github.com/thoughtbot/clearance/issues\n[Stack Overflow]: http://stackoverflow.com/questions/tagged/clearance\n\n## Getting Started\n\nClearance is a Rails engine tested against Rails `\u003e= 7.1` and Ruby `\u003e= 3.2.9`.\n\nYou can add it to your Gemfile with:\n\n```sh\ngem \"clearance\"\n```\n\nRun the bundle command to install it.\n\nAfter you install Clearance, you need to run the generator:\n\n```shell\nrails generate clearance:install\n```\n\nThe Clearance install generator:\n\n* Inserts `Clearance::User` into your `User` model\n* Inserts `Clearance::Controller` into your `ApplicationController`\n* Creates an initializer file to allow further configuration.\n* Creates a migration file that either create a users table or adds any necessary\n  columns to the existing table.\n\n## Configure\n\nOverride any of these defaults in `config/initializers/clearance.rb`:\n\n```ruby\nClearance.configure do |config|\n  config.allow_sign_up = true\n  config.allow_password_reset = true\n  config.cookie_domain = \".example.com\"\n  config.cookie_expiration = lambda { |cookies| 1.year.from_now.utc }\n  config.cookie_name = \"remember_token\"\n  config.cookie_path = \"/\"\n  config.routes = true\n  config.httponly = true\n  config.mailer_sender = \"reply@example.com\"\n  config.password_strategy = Clearance::PasswordStrategies::BCrypt\n  config.redirect_url = \"/\"\n  config.url_after_destroy = nil\n  config.url_after_denied_access_when_signed_out = nil\n  config.rotate_csrf_on_sign_in = true\n  config.same_site = nil\n  config.secure_cookie = Rails.configuration.force_ssl\n  config.signed_cookie = false\n  config.sign_in_guards = []\n  config.user_model = \"User\"\n  config.parent_controller = \"ApplicationController\"\n  config.sign_in_on_password_reset = false\nend\n```\n\n## Use\n\n### Access Control\n\nUse the `require_login` filter to control access to controller actions.\n\n```ruby\nclass ArticlesController \u003c ApplicationController\n  before_action :require_login\n\n  def index\n    current_user.articles\n  end\nend\n```\n\nClearance also provides routing constraints that can be used to control access\nat the routing layer:\n\n```ruby\nBlog::Application.routes.draw do\n  constraints Clearance::Constraints::SignedIn.new { |user| user.admin? } do\n    root to: \"admin/dashboards#show\", as: :admin_root\n  end\n\n  constraints Clearance::Constraints::SignedIn.new do\n    root to: \"dashboards#show\", as: :signed_in_root\n  end\n\n  constraints Clearance::Constraints::SignedOut.new do\n    root to: \"marketing#index\"\n  end\nend\n```\n\n### Helper Methods\n\nUse `current_user`, `signed_in?`, and `signed_out?` in controllers, views, and\nhelpers. For example:\n\n```erb\n\u003c% if signed_in? %\u003e\n  \u003c%= current_user.email %\u003e\n  \u003c%= button_to \"Sign out\", sign_out_path, method: :delete %\u003e\n\u003c% else %\u003e\n  \u003c%= link_to \"Sign in\", sign_in_path %\u003e\n\u003c% end %\u003e\n```\n\n### Password Resets\n\nWhen a user resets their password, Clearance delivers them an email. You\nshould change the `mailer_sender` default, used in the email's \"from\" header:\n\n```ruby\nClearance.configure do |config|\n  config.mailer_sender = \"reply@example.com\"\nend\n```\n\n### Multiple Domain Support\n\nYou can support multiple domains, or other special domain configurations by\noptionally setting `cookie_domain` as a callable object. The first argument\npassed to the method is an ActionDispatch::Request object.\n\n```ruby\nClearance.configure do |config|\n  config.cookie_domain = lambda { |request| request.host }\nend\n```\n\n### Integrating with Rack Applications\n\nClearance adds its session to the Rack environment hash so middleware and other\nRack applications can interact with it:\n\n```ruby\nclass Bubblegum::Middleware\n  def initialize(app)\n    @app = app\n  end\n\n  def call(env)\n    if env[:clearance].signed_in?\n      env[:clearance].current_user.bubble_gum\n    end\n\n    @app.call(env)\n  end\nend\n```\n\n## Overriding Clearance\n\n### Routes\n\nSee [config/routes.rb](/config/routes.rb) for the default set of routes.\n\nAs of Clearance 1.5 it is recommended that you disable Clearance routes and take\nfull control over routing and URL design. This ensures that your app's URL design\nwon't be affected if the gem's routes and URL design are changed.\n\nTo disable the routes, change the `routes` configuration option to false:\n\n```ruby\nClearance.configure do |config|\n  config.routes = false\nend\n```\n\nYou can optionally run `rails generate clearance:routes` to dump a copy of the\ndefault routes into your application for modification.\n\n### Controllers\n\nSee [app/controllers/clearance](/app/controllers/clearance) for the default\nbehavior. Many protected methods were extracted in these controllers in an\nattempt to make overrides and hooks simpler.\n\nTo override a Clearance controller, subclass it and update the routes to\npoint to your new controller (see the \"Routes\" section).\n\n```ruby\nclass PasswordsController \u003c Clearance::PasswordsController\nclass SessionsController \u003c Clearance::SessionsController\nclass UsersController \u003c Clearance::UsersController\n```\n\n### Redirects\n\nThe post-action redirects in Clearance are simple methods which can be\noverridden one by one, or configured globally.\n\nThese \"success\" methods are called for signed in users, and redirect to\n`Clearance.configuration.redirect_url` (which is `/` by default):\n\n- `passwords#url_after_update`\n- `sessions#url_after_create`\n- `sessions#url_for_signed_in_users`\n- `users#url_after_create`\n- `application#url_after_denied_access_when_signed_in`\n\nTo override them all at once, change the global configuration of `redirect_url`.\nTo change individual URLs, override the appropriate method in your subclassed\ncontroller.\n\nThese \"failure\" methods are called for signed out sessions:\n\n- `application#url_after_denied_access_when_signed_out`\n- `sessions#url_after_destroy`\n\nYou can override the appropriate method in your subclassed controller or you\ncan set a configuration value for either of these URLs:\n\n- `Clearance.configuration.url_after_denied_access_when_signed_out`\n- `Clearance.configuration.url_after_destroy`\n\nBoth configurations default to `nil` and if not set will default to\n`sign_in_url` in `sessions_controller.rb` and `authorization.rb` for backwards\ncompatibility.\n\n\n### Views\n\nSee [app/views](/app/views) for the default behavior.\n\nTo override a view, create your own copy of it:\n\n```\napp/views/clearance_mailer/change_password.html.erb\napp/views/passwords/create.html.erb\napp/views/passwords/edit.html.erb\napp/views/passwords/new.html.erb\napp/views/sessions/_form.html.erb\napp/views/sessions/new.html.erb\napp/views/users/_form.html.erb\napp/views/users/new.html.erb\n```\n\nYou can use the Clearance views generator to copy the default views to your\napplication for modification.\n\n```shell\nrails generate clearance:views\n```\n\n### Layouts\n\nBy default, Clearance uses your application's default layout. If you would like\nto change the layout that Clearance uses when rendering its views, simply\nspecify the layout in the `config/application.rb`\n\n```ruby\nconfig.to_prepare do\n  Clearance::PasswordsController.layout \"my_passwords_layout\"\n  Clearance::SessionsController.layout \"my_sessions_layout\"\n  Clearance::UsersController.layout \"my_admin_layout\"\nend\n```\n\n### Translations\n\nAll flash messages and email subject lines are stored in [i18n translations].\nOverride them like any other translation.\n\n[i18n translations]: http://guides.rubyonrails.org/i18n.html\n\nSee [config/locales/clearance.en.yml](/config/locales/clearance.en.yml) for the\ndefault behavior.\n\nYou can also install [clearance-i18n](https://github.com/thoughtbot/clearance-i18n)\nfor access to additional, user-contributed translations.\n\n### User Model\n\nSee [lib/clearance/user.rb](/lib/clearance/user.rb) for the default behavior.\nYou can override those methods as needed.\n\nNote that there are some model-level validations (see above link for detail)\nwhich the `Clearance::User` module will add to the configured model class and\nwhich may conflict with or duplicate already present validations on the `email`\nand `password` attributes. Over-riding the `email_optional?` or\n`skip_password_validation?` methods to return `true` will disable those\nvalidations from being added.\n\n### Signed Cookies\n\nBy default, Clearance uses unsigned cookies. If you would like to use signed\ncookies you can do so by overriding the default in an initializer like so:\n\n```ruby\nClearance.configure do |config|\n  # ... other overrides\n  config.signed_cookie = true\nend\n```\n\nIf you are currently not using signed cookies but would like to migrate your\nusers over to them without breaking current sessions, you can do so by passing\nin `:migrate` rather than `true` as so:\n\n```ruby\nClearance.configure do |config|\n  # ... other overrides\n  config.signed_cookie = :migrate\nend\n```\n\nYou can read more about signed cookies in Clearance and why they are a good idea\nin the [pull request that added them](https://github.com/thoughtbot/clearance/pull/917).\n\n\n## Extending Sign In\n\nBy default, Clearance will sign in any user with valid credentials. If you need\nto support additional checks during the sign in process then you can use the\nSignInGuard stack. For example, using the SignInGuard stack, you could prevent\nsuspended users from signing in, or require that users confirm their email\naddress before accessing the site.\n\n`SignInGuard`s offer fine-grained control over the process of\nsigning in a user. Each guard is run in order and hands the session off to\nthe next guard in the stack.\n\nA `SignInGuard` is an object that responds to `call`. It is initialized with a\nsession and the current stack.\n\nOn success, a guard should call the next guard or return `SuccessStatus.new` if\nyou don't want any subsequent guards to run.\n\nOn failure, a guard should call `FailureStatus.new(failure_message)`. It can\nprovide a message explaining the failure.\n\nFor convenience, a [SignInGuard](lib/clearance/sign_in_guard.rb) class has been\nprovided and can be inherited from. The convenience class provides a few methods\nto help make writing guards simple: `success`, `failure`, `next_guard`,\n`signed_in?`, and `current_user`.\n\nHere's an example custom guard to handle email confirmation:\n\n```ruby\nClearance.configure do |config|\n  config.sign_in_guards = [\"EmailConfirmationGuard\"]\nend\n```\n\n```ruby\n# app/guards/email_confirmation_guard.rb\nclass EmailConfirmationGuard \u003c Clearance::SignInGuard\n  def call\n    if unconfirmed?\n      failure(\"You must confirm your email address.\")\n    else\n      next_guard\n    end\n  end\n\n  def unconfirmed?\n    signed_in? \u0026\u0026 !current_user.confirmed_at\n  end\nend\n```\n\n## Testing\n\n### Fast Feature Specs\n\nClearance includes middleware that avoids wasting time spent visiting, loading,\nand submitting the sign in form. It instead signs in the designated user\ndirectly. The speed increase can be [substantial][backdoor].\n\n[backdoor]: http://robots.thoughtbot.com/post/37907699673/faster-tests-sign-in-through-the-back-door\n\nEnable the Middleware in Test:\n\n```ruby\n# config/environments/test.rb\nMyRailsApp::Application.configure do\n  # ...\n  config.middleware.use Clearance::BackDoor\n  # ...\nend\n```\n\nUsage:\n\n```ruby\nvisit root_path(as: user)\n```\n\nAdditionally, if `User#to_param` is overridden, you can pass a block in\norder to override the default behavior:\n\n```ruby\n# config/environments/test.rb\nMyRailsApp::Application.configure do\n  # ...\n  config.middleware.use Clearance::BackDoor do |username|\n    Clearance.configuration.user_model.find_by(username: username)\n  end\n  # ...\nend\n```\n\n### Ready Made Feature Specs\n\nIf you're using RSpec, you can generate feature specs to help prevent\nregressions in Clearance's integration with your Rails app over time. These\nfeature specs, will also require `factory_bot_rails`.\n\nTo Generate the clearance specs, run:\n\n```shell\nrails generate clearance:specs\n```\n\n### Controller Test Helpers\n\nTo test controller actions that are protected by `before_action :require_login`,\nrequire Clearance's test helpers in your test suite.\n\nFor `rspec`, add the following line to your `spec/rails_helper.rb` or\n`spec/spec_helper` if `rails_helper` does not exist:\n\n```ruby\nrequire \"clearance/rspec\"\n```\n\nFor `test-unit`, add this line to your `test/test_helper.rb`:\n\n```ruby\nrequire \"clearance/test_unit\"\n```\n\n**Note for Rails 5:** the default generated controller tests are now\nintegration tests. You will need to use the\n[backdoor middleware](#fast-feature-specs) instead.\n\nThis will make `Clearance::Controller` methods work in your controllers\nduring functional tests and provide access to helper methods like:\n\n```ruby\nsign_in\nsign_in_as(user)\nsign_out\n```\n\n### View and Helper Spec Helpers\n\nDoes the view or helper you're testing reference `signed_in?`, `signed_out?` or\n`current_user`? If you `require 'clearance/rspec'`, you will have the following\nhelpers available in your view specs:\n\n```ruby\nsign_in\nsign_in_as(user)\n```\n\nThese will make the clearance view helpers work as expected by signing in either\na new instance of your user model (`sign_in`) or the object you pass to\n`sign_in_as`. If you do not call one of these sign in helpers or otherwise set\n`current_user` in your view specs, your view will behave as if there is no\ncurrent user: `signed_in?` will be false and `signed_out?` will be true.\n\n## Contributing\n\nPlease see [CONTRIBUTING.md].\nThank you, [contributors]!\n\n[CONTRIBUTING.md]: /CONTRIBUTING.md\n[contributors]: https://github.com/thoughtbot/clearance/graphs/contributors\n\n## Security\n\nFor security issues it's better to contact \u003csecurity@thoughtbot.com\u003e (See \u003chttps://thoughtbot.com/security\u003e)\n\n## License\n\nClearance is copyright © 2009 thoughtbot. It is free software, and may be\nredistributed under the terms specified in the [`LICENSE`] file.\n\n[`LICENSE`]: /LICENSE\n\n\u003c!-- START /templates/footer.md --\u003e\n## About thoughtbot\n\n![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)\n\nThis repo is maintained and funded by thoughtbot, inc.\nThe names and logos for thoughtbot are trademarks of thoughtbot, inc.\n\nWe love open source software!\nSee [our other projects][community].\nWe are [available for hire][hire].\n\n[community]: https://thoughtbot.com/community?utm_source=github\n[hire]: https://thoughtbot.com/hire-us?utm_source=github\n\n\u003c!-- END /templates/footer.md --\u003e\n","funding_links":["https://github.com/sponsors/thoughtbot"],"categories":["User","Security","Ruby","用户","Authentication and OAuth"],"sub_categories":["Authentication","Rails Authentication","认证"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fclearance","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthoughtbot%2Fclearance","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fclearance/lists"}