{"id":13507398,"url":"https://github.com/paulanthonywilson/basic_auth","last_synced_at":"2026-02-20T00:32:24.613Z","repository":{"id":36232062,"uuid":"40536383","full_name":"paulanthonywilson/basic_auth","owner":"paulanthonywilson","description":"Elixir Plug to easily add HTTP basic authentication to an app","archived":false,"fork":false,"pushed_at":"2020-05-29T12:07:54.000Z","size":143,"stargazers_count":165,"open_issues_count":4,"forks_count":26,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-12-13T02:56:00.211Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/paulanthonywilson.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-11T10:38:59.000Z","updated_at":"2025-11-14T10:32:11.000Z","dependencies_parsed_at":"2022-09-09T11:40:57.538Z","dependency_job_id":null,"html_url":"https://github.com/paulanthonywilson/basic_auth","commit_stats":null,"previous_names":["cultivatehq/basic_auth"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/paulanthonywilson/basic_auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulanthonywilson%2Fbasic_auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulanthonywilson%2Fbasic_auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulanthonywilson%2Fbasic_auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulanthonywilson%2Fbasic_auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paulanthonywilson","download_url":"https://codeload.github.com/paulanthonywilson/basic_auth/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulanthonywilson%2Fbasic_auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29637411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T22:32:43.237Z","status":"ssl_error","status_checked_at":"2026-02-19T22:32:38.330Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2024-08-01T02:00:32.946Z","updated_at":"2026-02-20T00:32:24.585Z","avatar_url":"https://github.com/paulanthonywilson.png","language":"Elixir","readme":"# DEPRECATED\n\n`Plug.BasicAuth` is now part of [Plug](https://github.com/elixir-plug/plug).\n\n\n\n\n# BasicAuth\n\n\nThis is an Elixir Plug for adding basic authentication into an application.\n\nThe plug can be configured to use:\n\n1) Static username and password in application configuration\n\n-OR-\n\n2) Your own custom authentication function\n\nNote that if using option (1), prior to 2.2.1 the library was vulnerable to [timing attacks](https://codahale.com/a-lesson-in-timing-attacks/);\nwe suggest updating `~\u003e 2.2.2`.\n\nIf you are using your own custom authentication function, then you are are on your own.\n([Plug.Crypto.secure_compare/2](https://hexdocs.pm/plug/1.5.0-rc.0/Plug.Crypto.html#secure_compare/2) is something that may help you compare\nbinaries in constant time.)\n\n\n## How to use\n\nAdd the package as a dependency in your Elixir project using something along the lines of:\n```elixir\n  defp deps do\n    [{:basic_auth, \"~\u003e 2.2.2\"}]\n  end\n```\n\nAdd into the top of a controller, or into a router pipeline a plug declaration like:\n\n```elixir\nplug BasicAuth, use_config: {:your_app, :your_config}\n```\n\n  Where :your_app and :your_config should refer to values in your application config.\n\n  In your configuration you can set values directly, eg\n\n  ```elixir\n\n  config :your_app, your_config: [\n    username: \"admin\",\n    password: \"simple_password\",\n    realm: \"Admin Area\"\n  ]\n  ```\n\nAll configuration is read at runtime to support using\n[REPLACE_OS_VARS](http://michal.muskala.eu/2017/07/30/configuring-elixir-libraries.html#distillerys-replaceosvars)\nas part of a release.\n\n  or choose to get one (or all) from environment variables, eg\n\n  ```elixir\n  config :basic_auth, my_auth_with_system: [\n    username: {:system, \"BASIC_AUTH_USERNAME\"},\n    password: {:system, \"BASIC_AUTH_PASSWORD\"},\n    realm:    {:system, \"BASIC_AUTH_REALM\"}\n  ]\n  ```\n\nAlternatively you can provide a custom function to the plug to authenticate the user any way\nyou want, such as finding the user from a database.\n\n```elixir\n  plug BasicAuth, callback: \u0026User.find_by_username_and_password/3\n```\n\n  (or optionally provide a realm)\n\n```elixir\n  plug BasicAuth, callback: \u0026User.find_by_username_and_password/3, realm: \"Area 51\"\n```\n\nWhere :callback is your custom authentication function that takes a conn, username\nand a password and returns a conn. Your function must return `Plug.Conn.halt(conn)`\nif authentication fails, otherwise you can use `Plug.Conn.assign(conn, :current_user, ...)`\nto enhance the conn with variables or session for your controller.\n\nThe function must have an arity of 3, and be of the form\n\n```elixir\n@spec myfunction(Plug.Conn.t, String.t, String.t) :: Plug.Conn.t\n```\n\nIt will receive a connection, username, and password.\n\nEasy as that!\n\n\n### Authenticating with custom response body\n\nIf you want a custom unauthorised response body you can configure a `custom_response`:\n\n```elixir\nplug BasicAuth,\n    use_config: {:your_app, :your_config},\n    custom_response: \u0026YouApp.Helpers.unauthorized_response/1\n\n```\n\nor\n\n```elixir\n\nplug BasicAuth,\n    callback: \u0026User.find_by_username_and_password/3,\n    realm: \"Area 51\",\n    custom_response: \u0026YouApp.Helpers.unauthorized_response/1\n```\n\nWhere `:custom_response` is a custom response function that takes a `conn`. For example:\n\n```elixir\n\ndef unauthorized_response(conn) do\n    conn\n    |\u003e Plug.Conn.put_resp_content_type(\"application/json\")\n    |\u003e Plug.Conn.send_resp(401, ~s[{\"message\": \"Unauthorized\"}])\n  end\n\n```\n\n\n### Authenticating only for specific actions\n\n\nIf you're looking to authenticate only for a subset of actions in a controller you can use plug's `when action in` syntax as shown below\n\n```elixir\nplug BasicAuth, [use_config: {: your_app, : your_config}] when action in [:edit, :delete]\n```\n\n  additionally you can exclude specific actions using `not`\n\n```elixir\nplug BasicAuth, [use_config: {: your_app, : your_config}] when not action in [:index, :show]\n```\n## Testing controllers with Basic Auth\n\nIf you're storing credentials within configuration files, we can reuse them within our test files\ndirectly using snippets like `Application.get_env(:basic_auth)[:username]`.\n\n### Update Tests to insert a basic authentication header\n\nAny controller that makes use of basic authentication, will need an additional header injected into\nthe connection in order for your tests to continue to work. The following is a brief snippet of how\nto get started. There is a more detailed\n[blog post](http://www.cultivatehq.com/posts/add-basic-authentication-to-a-phoenix-application/) that\nexplains a bit more about what needs to be done.\n\nAt the top of my controller test I have something that looks like:\n\n```elixir\n@username Application.get_env(:the_app, :basic_auth)[:username]\n@password Application.get_env(:the_app, :basic_auth)[:password]\n\ndefp using_basic_auth(conn, username, password) do\n  header_content = \"Basic \" \u003c\u003e Base.encode64(\"#{username}:#{password}\")\n  conn |\u003e put_req_header(\"authorization\", header_content)\nend\n```\n\nThen for any tests, I can simply pipe in this helper method to the connection process:\n```elixir\ntest \"GET / successfully renders when basic auth credentials supplied\", %{conn: conn} do\n  conn = conn\n    |\u003e using_basic_auth(@username, @password)\n    |\u003e get(\"/admin/users\")\n\n  assert html_response(conn, 200) =~ \"Users\"\nend\n```\n\nAnd a test case without basic auth for completeness:\n```elixir\ntest \"GET / without basic auth credentials prevents access\", %{conn: conn} do\n  conn = conn\n    |\u003e get(\"/admin/users\")\n\n  assert response(conn, 401) =~ \"401 Unauthorized\"\nend\n```\n","funding_links":[],"categories":["Authentication"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulanthonywilson%2Fbasic_auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulanthonywilson%2Fbasic_auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulanthonywilson%2Fbasic_auth/lists"}