diff --git a/CHANGELOG.md b/CHANGELOG.md index ab950cbfe..dc9ec639e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## v2.2.0 +### Enhancement + +* Add `:scheme` option to `Guardian.Plug.VerifyHeader` + +### Deprecation + +* `:scheme` option configuration of `Guardian.Plug.VerifyHeader` is deprecated + please use `:scheme` instead. ## v2.1.2 ### Enhancement * Documentation improvements diff --git a/README.md b/README.md index f3046d7ff..92b2b670b 100644 --- a/README.md +++ b/README.md @@ -434,7 +434,8 @@ For more in-depth documentation please see the [GuardianDb README](https://githu ### How to add the token to a request (the Phoenix way) -Assuming you are using the default realm `Bearer` for the `Authorization` header: +Assuming you are using the default authentication scheme `Bearer` for +the `Authorization` header: ```elixir defmodule HelloWeb.AuthControllerTest do diff --git a/lib/guardian/plug/pipeline.ex b/lib/guardian/plug/pipeline.ex index 42d1d7b70..587e209e5 100644 --- a/lib/guardian/plug/pipeline.ex +++ b/lib/guardian/plug/pipeline.ex @@ -23,7 +23,7 @@ if Code.ensure_loaded?(Plug) do @claims %{iss: "IssuerApp"} plug Guardian.Plug.VerifySession, claims: @claims - plug Guardian.Plug.VerifyHeader, claims: @claims, realm: "Bearer" + plug Guardian.Plug.VerifyHeader, claims: @claims, scheme: "Bearer" plug Guardian.Plug.EnsureAuthenticated plug Guardian.Plug.LoadResource, allow_blank: true end @@ -90,7 +90,7 @@ if Code.ensure_loaded?(Plug) do ```elixir plug Guardian.Plug.Pipeline, module: MyApp.Tokens, error_handler: MyApp.AuthErrorHandler - plug Guardian.VerifyHeader, realm: "Bearer" + plug Guardian.VerifyHeader, scheme: "Bearer" ``` Inline pipelines are also good to change the error handler that you want to use. @@ -101,7 +101,7 @@ if Code.ensure_loaded?(Plug) do # Use the MyApp.AuthErrorHandler for downstream Guardian plugs plug Guardian.Plug.Pipeline, module: MyApp.Tokens, error_handler: MyApp.AuthErrorHandler - plug Guardian.VerifyHeader, realm: "Bearer" + plug Guardian.VerifyHeader, scheme: "Bearer" # Now change out the error handler for plugs downstream of this one. plug Guardian.Plug.Pipeline, error_handler: MyApp.SpecialAuthErrorHandler diff --git a/lib/guardian/plug/verify_header.ex b/lib/guardian/plug/verify_header.ex index 02b9963aa..4d599c669 100644 --- a/lib/guardian/plug/verify_header.ex +++ b/lib/guardian/plug/verify_header.ex @@ -32,7 +32,7 @@ if Code.ensure_loaded?(Plug) do * `claims` - The literal claims to check to ensure that a token is valid * `max_age` - If the token has an "auth_time" claim, check it is not older than the maximum age. * `header_name` - The name of the header to search for a token. Defaults to `authorization`. - * `realm` - The prefix for the token in the header. Defaults to `Bearer`. + * `scheme` - The prefix for the token in the header. Defaults to `Bearer`. `:none` will not use a prefix. * `key` - The location to store the information in the connection. Defaults to: `default` * `halt` - Whether to halt the connection in case of error. Defaults to `true`. @@ -76,19 +76,9 @@ if Code.ensure_loaded?(Plug) do @impl Plug @spec init(opts :: Keyword.t()) :: Keyword.t() def init(opts \\ []) do - realm = Keyword.get(opts, :realm, "Bearer") - - case realm do - "" -> - opts - - :none -> - opts - - _realm -> - {:ok, reg} = Regex.compile("#{realm}\:?\s+(.*)$", "i") - Keyword.put(opts, :realm_reg, reg) - end + opts + |> get_scheme() + |> put_scheme_reg(opts) end @impl Plug @@ -115,6 +105,28 @@ if Code.ensure_loaded?(Plug) do end end + defp put_scheme_reg("", opts) do + opts + end + + defp put_scheme_reg(:none, opts) do + opts + end + + defp put_scheme_reg(scheme, opts) do + {:ok, reg} = Regex.compile("#{scheme}\:?\s+(.*)$", "i") + Keyword.put(opts, :scheme_reg, reg) + end + + defp get_scheme(opts) do + if Keyword.has_key?(opts, :realm) do + IO.warn("`:realm` option is deprecated; please rename `:realm` to `:scheme` option instead.") + Keyword.get(opts, :realm, "Bearer") + else + Keyword.get(opts, :scheme, "Bearer") + end + end + defp handle_error(conn, :token_expired = reason, opts) do if refresh_from_cookie_opts = fetch_refresh_from_cookie_options(opts) do Guardian.Plug.VerifyCookie.refresh_from_cookie(conn, refresh_from_cookie_opts) @@ -157,7 +169,7 @@ if Code.ensure_loaded?(Plug) do defp fetch_token_from_header(_, _, []), do: :no_token_found defp fetch_token_from_header(conn, opts, [token | tail]) do - reg = Keyword.get(opts, :realm_reg, ~r/^(.*)$/) + reg = Keyword.get(opts, :scheme_reg, ~r/^(.*)$/) trimmed_token = String.trim(token) case Regex.run(reg, trimmed_token) do diff --git a/mix.exs b/mix.exs index c41923680..569d4f633 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule Guardian.Mixfile do @moduledoc false use Mix.Project - @version "2.1.2" + @version "2.2.0" @url "https://github.com/ueberauth/guardian" @maintainers [ "Daniel Neighman", diff --git a/test/guardian/plug/verify_header_test.exs b/test/guardian/plug/verify_header_test.exs index af1be9d33..8fb8fba09 100644 --- a/test/guardian/plug/verify_header_test.exs +++ b/test/guardian/plug/verify_header_test.exs @@ -2,12 +2,13 @@ defmodule Guardian.Plug.VerifyHeaderTest do @moduledoc false use Plug.Test + use ExUnit.Case, async: true + + import ExUnit.CaptureIO alias Guardian.Plug.Pipeline alias Guardian.Plug.VerifyHeader - use ExUnit.Case, async: true - defmodule Handler do @moduledoc false @@ -116,6 +117,23 @@ defmodule Guardian.Plug.VerifyHeaderTest do assert Guardian.Plug.current_claims(conn, key: :secret) == ctx.claims end + test "with :realm option shows a warning message" do + has_warning_message = + :stderr + |> capture_io(fn -> VerifyHeader.init(realm: "Bearer") end) + |> String.contains?("`:realm` option is deprecated; please rename `:realm` to `:scheme` option instead.") + + assert has_warning_message + end + + test "getting the scheme config" do + opts = VerifyHeader.init(realm: "Bearer") + assert opts[:scheme_reg] == ~r/Bearer:? +(.*)$/i + + opts = VerifyHeader.init(scheme: "Basic") + assert opts[:scheme_reg] == ~r/Basic:? +(.*)$/i + end + test "with a token and mismatching claims", ctx do conn = :get