ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - paulanthonywilson/basic_auth: Elixir Plug to easily add HTTP basic authentication to an app
Elixir Plug to easily add HTTP basic authentication to an app - paulanthonywilson/basic_auth
Visit Site

GitHub - paulanthonywilson/basic_auth: Elixir Plug to easily add HTTP basic authentication to an app

GitHub - paulanthonywilson/basic_auth: Elixir Plug to easily add HTTP basic authentication to an app

DEPRECATED

Plug.BasicAuth is now part of Plug.

BasicAuth

This is an Elixir Plug for adding basic authentication into an application.

The plug can be configured to use:

  1. Static username and password in application configuration

-OR-

  1. Your own custom authentication function

Note that if using option (1), prior to 2.2.1 the library was vulnerable to timing attacks; we suggest updating ~> 2.2.2.

If you are using your own custom authentication function, then you are are on your own. (Plug.Crypto.secure_compare/2 is something that may help you compare binaries in constant time.)

How to use

Add the package as a dependency in your Elixir project using something along the lines of:

  defp deps do
    [{:basic_auth, "~> 2.2.2"}]
  end

Add into the top of a controller, or into a router pipeline a plug declaration like:

plug BasicAuth, use_config: {:your_app, :your_config}

Where :your_app and :your_config should refer to values in your application config.

In your configuration you can set values directly, eg


config :your_app, your_config: [
  username: "admin",
  password: "simple_password",
  realm: "Admin Area"
]

All configuration is read at runtime to support using REPLACE_OS_VARS as part of a release.

or choose to get one (or all) from environment variables, eg

config :basic_auth, my_auth_with_system: [
  username: {:system, "BASIC_AUTH_USERNAME"},
  password: {:system, "BASIC_AUTH_PASSWORD"},
  realm:    {:system, "BASIC_AUTH_REALM"}
]

Alternatively you can provide a custom function to the plug to authenticate the user any way you want, such as finding the user from a database.

  plug BasicAuth, callback: &User.find_by_username_and_password/3

(or optionally provide a realm)

  plug BasicAuth, callback: &User.find_by_username_and_password/3, realm: "Area 51"

Where :callback is your custom authentication function that takes a conn, username and a password and returns a conn. Your function must return Plug.Conn.halt(conn) if authentication fails, otherwise you can use Plug.Conn.assign(conn, :current_user, ...) to enhance the conn with variables or session for your controller.

The function must have an arity of 3, and be of the form

@spec myfunction(Plug.Conn.t, String.t, String.t) :: Plug.Conn.t

It will receive a connection, username, and password.

Easy as that!

Authenticating with custom response body

If you want a custom unauthorised response body you can configure a custom_response:

plug BasicAuth,
    use_config: {:your_app, :your_config},
    custom_response: &YouApp.Helpers.unauthorized_response/1

or


plug BasicAuth,
    callback: &User.find_by_username_and_password/3,
    realm: "Area 51",
    custom_response: &YouApp.Helpers.unauthorized_response/1

Where :custom_response is a custom response function that takes a conn. For example:


def unauthorized_response(conn) do
    conn
    |> Plug.Conn.put_resp_content_type("application/json")
    |> Plug.Conn.send_resp(401, ~s[{"message": "Unauthorized"}])
  end

Authenticating only for specific actions

If 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

plug BasicAuth, [use_config: {: your_app, : your_config}] when action in [:edit, :delete]

additionally you can exclude specific actions using not

plug BasicAuth, [use_config: {: your_app, : your_config}] when not action in [:index, :show]

Testing controllers with Basic Auth

If you're storing credentials within configuration files, we can reuse them within our test files directly using snippets like Application.get_env(:basic_auth)[:username].

Update Tests to insert a basic authentication header

Any controller that makes use of basic authentication, will need an additional header injected into the connection in order for your tests to continue to work. The following is a brief snippet of how to get started. There is a more detailed blog post that explains a bit more about what needs to be done.

At the top of my controller test I have something that looks like:

@username Application.get_env(:the_app, :basic_auth)[:username]
@password Application.get_env(:the_app, :basic_auth)[:password]

defp using_basic_auth(conn, username, password) do
  header_content = "Basic " <> Base.encode64("#{username}:#{password}")
  conn |> put_req_header("authorization", header_content)
end

Then for any tests, I can simply pipe in this helper method to the connection process:

test "GET / successfully renders when basic auth credentials supplied", %{conn: conn} do
  conn = conn
    |> using_basic_auth(@username, @password)
    |> get("/admin/users")

  assert html_response(conn, 200) =~ "Users"
end

And a test case without basic auth for completeness:

test "GET / without basic auth credentials prevents access", %{conn: conn} do
  conn = conn
    |> get("/admin/users")

  assert response(conn, 401) =~ "401 Unauthorized"
end

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory