Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guardian V1 Support #49

Open
hassox opened this issue May 31, 2017 · 3 comments
Open

Guardian V1 Support #49

hassox opened this issue May 31, 2017 · 3 comments

Comments

@hassox
Copy link

hassox commented May 31, 2017

Hi

I've been working on getting a release together for Guardian v1. This release is
significantly different (in a good way!).

The big difference in V1 is the use of an implementation module, allowing for
multiple configurations per project.

Guardian V1 allows for:

  • Supporting token types other than JWT
  • Supporting multiple configurations in a single project
  • Pipelining of Guardian plugs
  • Extracting phoenix helpers into a different project
  • Better hooking Support
  • Moves the serializer into the implementation module

To get started with V1 developers need to create a 'token module'.

  defmodule MyApp.AuthTokens do
    use Guardian, otp_app: :my_app

    def subject_for_token(resource, _claims), do: to_string(resource.id)
    def resource_from_claims(claims) do
      find_me_a_resource(claims["sub"])
    end
  end

Once you have your implementation module (a bare bones one is above) you can use that directly:

MyApp.AuthTokens.encode_and_sign(resource, claims, opts)
MyApp.AuthTokens.decode_and_verify(token, claims_to_check, opts)

Or, for library authors such as yourself

Guardian.encode_and_sign(MyApp.AuthTokens, resource, claims, opts)
Guardian.decode_and_verify(MyApp.AuthTokens, token, claims_to_check, opts)

We've also disambiguated setting token type, ttl and the key from the claims. These are now set via the options.

Guardian.encode_and_sign(MyApp.AuthTokens, resource, claims, token_type: "access", key: :secret, ttl: {1, :week})

Secrets and configuration values also got an overhaul. Any value can be of the form:

  • {:system, "KEY"}
  • {mod, :func}
  • {mod, :func, [args]}
  • fn -> some_value end
  • or a literal value

These configuration options can be set either in the configuration or in the implementation module as options to use Guardian

Pipelines

All plugs require being set as part of a pipeline. Pipelines put the implementation module and error handler on the conn.

You can set these directly with Guardian.Pipeline or create a pipeline module

plug Guardian.Pipeline, module: MyApp.AuthTokens, error_handler: MyApp.AuthErrorHandler

OR

  defmodule MyApp.AuthPipeline do
    use Guardian.Plug.Pipeline, otp_app: :my_app,
                                module: MyApp.Tokens,
                                error_handler: MyApp.AuthErrorHandler

    alias Guardian.Plug.{
      EnsureAuthenticated,
      LoadResource,
      VerifySession,
      VerifyHeader,
    }

    plug VerifySession, claims: @claims
    plug VerifyHeader, claims: @claims, realm: "Bearer"
    plug EnsureAuthenticated
    plug LoadResource, ensure: true
  end

With usage

plug MyApp.AuthPipeline

I expect that this will be a pre-release within about a week.
I'd love to get feedback on it before it goes full version 1.

@britton-jb
Copy link
Owner

britton-jb commented May 31, 2017

@hassox Thanks for sending this my way. Very excited about the pipeline change. In a branch I'm working on accomplishing the same kind of functionality so seeing this is awesome.

The timing also works out well, as my lockable module was going to implement some breaking changes, so this will work nicely into the next version.

Supporting token types other than JWT

Just a lack of knowledge on my part, but can you give examples of that?

Everything else looks very straight forward, so I'll take a look at the docs and let you know if I have any other questions.

@hassox
Copy link
Author

hassox commented Jun 1, 2017

Hey @britton-jb

The new version allows multiple modules to be configured. As part of that, each module specifies a token_module. This module is setup as a behaviour (see Guardian.Token) So long as the token module conforms to the behaviour then it should be fine. The only type of token that Guardian supports out of the box is still JWT but this mechanism allows 3rd party token modules to be created. It's in response to some requests we've had. I have no current plans to implement another type of token but the possibility is there moving forward.

The most immediate use case of this functionality I think is to allow support for specific producers (like Auth0) although a full token module wouldn't be needed for that. Only a change to the verifier and a specific secret lookup.

We've tried to keep it as backward compatible as possible but still push though cleanup of various apis and the overall structure of the lib.

If you want hit me up on Slack and I'll try and answer any questions you have mate :)

@britton-jb
Copy link
Owner

Sounds great. Thanks for all of the hard work on Guardian.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants