Go login handlers for authentication providers (OAuth1, OAuth2)

gologin Build Status GoDoc

Package gologin provides chainable login http.Handler's for Google, Github, Twitter, Facebook, Bitbucket, Tumblr, or any OAuth1 or OAuth2 authentication providers.

Choose a subpackage. Register the LoginHandler and CallbackHandler for web logins or the TokenHandler for (mobile) token logins. Get the authenticated user or access token from the request context.

See examples for tutorials with apps you can run from the command line.

Features

  • LoginHandler and CallbackHandler support web login flows
  • TokenHandler supports native mobile token login flows
  • Obtain the user or access token from the context
  • Configurable OAuth 2 state parameter handling (CSRF protection)
  • Configurable OAuth 1 request secret handling

Install

go get github.com/dghubble/gologin

Docs

Read GoDoc or check the examples.

Overview

Package gologin provides http.Handler's which can be chained together to implement authorization flows by passing data (e.g. tokens, users) via the request context. gologin handlers take success and failure next http.Handler's to be called when authentication succeeds or fails. Chaining allows advanced customization, if desired. Once authentication succeeds, your success handler will have access to the user's access token and associated User/Account.

Usage

Choose a subpackage such as github or twitter. LoginHandler and Callback http.Handler's chain together lower level oauth1 or oauth2 handlers to authenticate users and fetch the Github or Twitter User, before calling your success http.Handler.

Let's walk through Github and Twitter web login examples.

Github OAuth2

Register the LoginHandler and CallbackHandler on your http.ServeMux.

config := &oauth2.Config{
    ClientID:     "GithubClientID",
    ClientSecret: "GithubClientSecret",
    RedirectURL:  "http://localhost:8080/callback",
    Endpoint:     githubOAuth2.Endpoint,
}
mux := http.NewServeMux()
stateConfig := gologin.DebugOnlyCookieConfig
mux.Handle("/login", github.StateHandler(stateConfig, github.LoginHandler(config, nil)))
mux.Handle("/callback", github.StateHandler(stateConfig, github.CallbackHandler(config, issueSession(), nil)))

The StateHandler checks for an OAuth2 state parameter cookie, generates a non-guessable state as a short-lived cookie if missing, and passes the state value in the ctx. The CookieConfig allows the cookie name or expiration (default 60 seconds) to be configured. In production, use a config like gologin.DefaultCookieConfig which sets Secure true to require cookies be sent over HTTPS. If you wish to persist state parameters a different way, you may chain your own http.Handler. (info)

The github LoginHandler reads the state from the ctx and redirects to the AuthURL (at github.com) to prompt the user to grant access. Passing nil for the failure handler just means the DefaultFailureHandler should be used, which reports errors. (info)

The github CallbackHandler receives an auth code and state OAuth2 redirection, validates the state against the state in the ctx, and exchanges the auth code for an OAuth2 Token. The github CallbackHandler wraps the lower level oauth2 CallbackHandler to further use the Token to obtain the Github User before calling through to the success or failure handlers.

Next, write the success http.Handler to do something with the Token and Github User added to the ctx.

func issueSession() http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
        ctx := req.Context()
        token, _ := oauth2Login.TokenFromContext(ctx)
        githubUser, err := github.UserFromContext(ctx)
        // handle errors and grant the visitor a session (cookie, token, etc.)
    }
    return http.HandlerFunc(fn)
}

See the Github tutorial for a web app you can run from the command line.

Twitter OAuth1

Register the LoginHandler and CallbackHandler on your http.ServeMux.

config := &oauth1.Config{
    ConsumerKey:    "TwitterConsumerKey",
    ConsumerSecret: "TwitterConsumerSecret",
    CallbackURL:    "http://localhost:8080/callback",
    Endpoint:       twitterOAuth1.AuthorizeEndpoint,
}
mux := http.NewServeMux()
mux.Handle("/login", twitter.LoginHandler(config, nil))
mux.Handle("/callback", twitter.CallbackHandler(config, issueSession(), nil))

The twitter LoginHandler obtains a request token and secret, adds them to the ctx, and redirects to the AuthorizeURL to prompt the user to grant access. Passing nil for the failure handler just means the DefaultFailureHandler should be used, which reports errors. (info)

The twitter CallbackHandler receives an OAuth1 token and verifier, reads the request secret from the ctx, and obtains an OAuth1 access token and secret. The twitter CallbackHandler wraps the lower level oauth1 CallbackHandler to further use the access token/secret to obtain the Twitter User before calling through to the success or failure handlers.

Next, write the success http.Handler to do something with the access token/secret and Twitter User added to the ctx.

func success() http.Handler {
    fn := func(w http.ResponseWriter, req *http.Request) {
        ctx := req.Context()
        accessToken, accessSecret, _ := oauth1Login.AccessTokenFromContext(ctx)
        twitterUser, err := twitter.UserFromContext(ctx)
        // handle errors and grant the visitor a session (cookie, token, etc.)
    }
    return http.HandlerFunc(fn)
}

*Note: Some OAuth1 providers (not Twitter), require the request secret be persisted until the callback is received. For this reason, the lower level oauth1 package splits LoginHandler functionality into a LoginHandler and AuthRedirectHandler. Provider packages, like tumblr, chain these together for you, but the lower level handlers are there if needed.

See the Twitter tutorial for a web app you can run from the command line.

State Parameters

OAuth2 StateHandler implements OAuth 2 RFC 6749 10.12 CSRF Protection using non-guessable values in short-lived HTTPS-only cookies to provide reasonable assurance the user in the login phase and callback phase are the same. If you wish to implement this differently, write a http.Handler which sets a state in the ctx, which is expected by LoginHandler and CallbackHandler.

You may use oauth2.WithState(context.Context, state string) for this. docs

Failure Handlers

If you wish to define your own failure http.Handler, you can get the error from the ctx using gologin.ErrorFromContext(ctx).

Mobile

Twitter includes a TokenHandler which can be useful for building APIs for mobile devices which use Login with Twitter.

Goals

Create small, chainable handlers to correctly implement the steps of common authentication flows. Handle provider-specific validation requirements.

Motivations

Package gologin implements authorization flow steps with chained handlers.

  • Authentication should be performed with chainable handlers to allow customization, swapping, or adding additional steps easily.
  • Authentication should be orthogonal to the session system. Let users choose their session/token library.
  • OAuth2 State CSRF should be included out of the box, but easy to customize.
  • Packages should import only what is required. OAuth1 and OAuth2 packages are separate.
  • http.Handler and context are powerful, flexible, and in the standard library.

Projects goth and gomniauth aim to provide a similar login solution with a different design. Check them out if you decide you don't like the ideas in gologin.

Contributing

New auth providers can be implemented by composing the handlers in the oauth1 or oauth2 subpackages. See the Contributing Guide.

License

MIT License

Owner
Dalton Hubble
Friends with the machines | Kubernetes | @poseidon Typhoon and Matchbox | Previously @lyft, @coreos, @twitter, MIT
Dalton Hubble
Comments
  • Update Google API version

    Update Google API version

    The Google API module renamed Userinfoplus to Userinfo; this can lead to incompatibilties when using gologin with other Google API packages.

    This commit updates the dependency version for the Google API wrapper and replaces references to Userinfoplus with simply Userinfo.

  • Use Standard library context in Go 1.7

    Use Standard library context in Go 1.7

    I wanted to build on top this library. But first I wanted to use the new context pkg in GO 1.7. I figured I will send a pr, in case you are interested to merge it.

  • 
Fix function comments based on best practices from Effective Go

    Fix function comments based on best practices from Effective Go

    Every exported function in a program should have a doc comment. The first sentence should be a summary that starts with the name being declared. From effective go.

    PR generated by CodeLingo. Install here to drive Continuous Higher Standards.

  • github: support enterprise instances

    github: support enterprise instances

    Thanks for making a wonderful library!

    This PR adds support for GitHub Enterprise instances. It looks at the AuthURL endpoint to infer whether the GitHub instance is github.com or an enterprise instance.

  • Use base64.URLEncoding instead of base64.StdEncoding for state parameter

    Use base64.URLEncoding instead of base64.StdEncoding for state parameter

    standard base64 encoding may contain a space characters and there are some situations when session has state with '+' characters but request comes in with ' ' instead of '+'

  • Add support for Apple sign in

    Add support for Apple sign in

    Here's an attempt to add support for Apple sign in, along with a working example and tests.

    Test coverage could be improved, which I am happy to do should there be interest in pulling this in.

  • Use base64.RawURLEncoding for StateHandler's state param

    Use base64.RawURLEncoding for StateHandler's state param

    • Avoid using '+' in the state param. A random state value may contain it and some OAuth 2 providers do not correctly URL encode their callback URLs. As a result, the parsed and checked state doesn't match.
    • See #12
  • Bump github.com/dghubble/sling from 1.4.0 to 1.4.1

    Bump github.com/dghubble/sling from 1.4.0 to 1.4.1

    Bumps github.com/dghubble/sling from 1.4.0 to 1.4.1.

    Release notes

    Sourced from github.com/dghubble/sling's releases.

    v1.4.1

    • Update minimum Go version from v1.16 to v1.18 (#76)
    Changelog

    Sourced from github.com/dghubble/sling's changelog.

    v1.4.1

    • Update minimum Go version to v1.18 (#76)
    Commits
    • 94c872b Update minimum Go version from v1.16 to v1.18
    • fac8477 Add go 1.19 to test matrix
    • 62be7c2 Update Go test matrix to add Go v1.18
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Bump google.golang.org/api from 0.103.0 to 0.104.0

    Bump google.golang.org/api from 0.103.0 to 0.104.0

    Bumps google.golang.org/api from 0.103.0 to 0.104.0.

    Release notes

    Sourced from google.golang.org/api's releases.

    v0.104.0

    0.104.0 (2022-12-07)

    Features

    Bug Fixes

    • idtoken: Increase MaxIdleConnsPerHost to 100 in NewClient (#1754) (629e217), refs #1744
    • transport/grpc: Separate resolution of creds and certs (#1759) (c213153)

    Documentation

    Changelog

    Sourced from google.golang.org/api's changelog.

    0.104.0 (2022-12-07)

    Features

    Bug Fixes

    • idtoken: Increase MaxIdleConnsPerHost to 100 in NewClient (#1754) (629e217), refs #1744
    • transport/grpc: Separate resolution of creds and certs (#1759) (c213153)

    Documentation

    Commits
    • 9255b0b chore(main): release 0.104.0 (#1748)
    • 4238314 chore: ignore some golang.org/x/* dependencies in renovate (#1772)
    • 029b659 chore(all): update all (#1768)
    • f819644 feat(all): auto-regenerate discovery clients (#1771)
    • 2b596d9 feat(all): auto-regenerate discovery clients (#1767)
    • 3195ce1 feat(all): auto-regenerate discovery clients (#1766)
    • 97a9846 feat(all): auto-regenerate discovery clients (#1760)
    • 8d8f0a7 feat(transport): de-experiment google-c2p resolver (#1757)
    • c213153 fix(transport/grpc): separate resolution of creds and certs (#1759)
    • 629e217 fix(idtoken): increase MaxIdleConnsPerHost to 100 in NewClient (#1754)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Bump github.com/dghubble/oauth1 from 0.7.1 to 0.7.2

    Bump github.com/dghubble/oauth1 from 0.7.1 to 0.7.2

    Bumps github.com/dghubble/oauth1 from 0.7.1 to 0.7.2.

    Release notes

    Sourced from github.com/dghubble/oauth1's releases.

    v0.7.2

    • Update minimum Go version from v1.17 to v1.18 (#66)
    Changelog

    Sourced from github.com/dghubble/oauth1's changelog.

    v0.7.2

    • Update minimum Go version from v1.17 to v1.18 (#66)
    Commits
    • 1445aad Update minimum Go version from v1.17 to v1.18
    • 953dec3 Bump github.com/stretchr/testify from 1.8.0 to 1.8.1
    • 56d749b Add go 1.19 to test matrix
    • 6f7198a Bump github.com/stretchr/testify from 1.7.5 to 1.8.0
    • 2e9b39a Bump github.com/stretchr/testify from 1.7.4 to 1.7.5
    • 52fe671 Bump github.com/stretchr/testify from 1.7.2 to 1.7.4
    • 4590427 Bump github.com/stretchr/testify from 1.7.1 to 1.7.2
    • 74c7d89 Update Go test matrix to add Go v1.18
    • dec88a1 Bump github.com/stretchr/testify from 1.7.0 to 1.7.1
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Bump google.golang.org/api from 0.91.0 to 0.92.0

    Bump google.golang.org/api from 0.91.0 to 0.92.0

    Bumps google.golang.org/api from 0.91.0 to 0.92.0.

    Release notes

    Sourced from google.golang.org/api's releases.

    v0.92.0

    0.92.0 (2022-08-10)

    Features

    Changelog

    Sourced from google.golang.org/api's changelog.

    0.92.0 (2022-08-10)

    Features

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Add SameSite attribute to the OAuth2 state cookie

    Add SameSite attribute to the OAuth2 state cookie

    • Add SameSite to the CookieConfig to allow configuring the SameSite attribute on the temporary state cookie used by OAuth2
    • Set strict mode on the DefaultCookieConfig
    • Set none mode on the DebugOnlyCookieConfig
JWT login microservice with plugable backends such as OAuth2, Google, Github, htpasswd, osiam, ..
JWT login microservice with plugable backends such as OAuth2, Google, Github, htpasswd, osiam, ..

loginsrv loginsrv is a standalone minimalistic login server providing a JWT login for multiple login backends. ** Attention: Update to v1.3.0 for Goog

Dec 24, 2022
JWT login microservice with plugable backends such as OAuth2, Google, Github, htpasswd

login-service login-service is a standalone minimalistic login server providing a (JWT)[https://jwt.io/] login for multiple login backends. Abstract l

Feb 12, 2022
A single sign-on solution based on go-oauth2 / oauth2 and gin-gonic/gin

A single sign-on solution based on go-oauth2 / oauth2 and gin-gonic/gin

Nov 17, 2021
Oauth2-golang - Oauth2 Golang Mysql

Oauth2-golang - Oauth2 Golang Mysql

Sep 16, 2022
Hazelcast Storage for go-oauth2/oauth2

Hazelcast Storage for go-oauth2/oauth2

Jan 26, 2022
A reverse proxy that provides authentication with Google, Github or other providers.
A reverse proxy that provides authentication with Google, Github or other providers.

A reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) to validate accounts by email, domain or group.

Jan 8, 2023
A reverse proxy that provides authentication with Google, Github or other providers.
A reverse proxy that provides authentication with Google, Github or other providers.

A reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) to validate accounts by email, domain

Jan 1, 2023
Scaffold to help building Terraform Providers using AWS IAM authentication.

Terraform Provider Scaffolding This repository is a template for a Terraform provider. It is intended as a starting point for creating Terraform provi

Mar 31, 2022
Authelia: an open-source authentication and authorization server providing two-factor authentication
Authelia: an open-source authentication and authorization server providing two-factor authentication

Authelia is an open-source authentication and authorization server providing two

Jan 5, 2022
Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication
Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Jan 8, 2023
A simple passwordless authentication middleware that uses only email as the authentication provider
A simple passwordless authentication middleware that uses only email as the authentication provider

email auth A simple passwordless authentication middleware that uses only email as the authentication provider. Motivation I wanted to restrict access

Jul 27, 2022
Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Authorization and authentication. Learning go by writing a simple authentication and authorization service.

Aug 5, 2022
⛩️ Go library for protecting HTTP handlers with authorization bearer token.

G8, pronounced Gate, is a simple Go library for protecting HTTP handlers with tokens. Tired of constantly re-implementing a security layer for each

Nov 14, 2022
:closed_lock_with_key: Middleware for keeping track of users, login states and permissions

Permissions2 Middleware for keeping track of users, login states and permissions. Online API Documentation godoc.org Features and limitations Uses sec

Dec 31, 2022
simple-jwt-provider - Simple and lightweight provider which exhibits JWTs, supports login, password-reset (via mail) and user management.

Simple and lightweight JWT-Provider written in go (golang). It exhibits JWT for the in postgres persisted user, which can be managed via api. Also, a password-reset flow via mail verification is available. User specific custom-claims also available for jwt-generation and mail rendering.

Dec 18, 2022
an SSO and OAuth / OIDC login solution for Nginx using the auth_request module
an SSO and OAuth / OIDC login solution for Nginx using the auth_request module

Vouch Proxy An SSO solution for Nginx using the auth_request module. Vouch Proxy can protect all of your websites at once. Vouch Proxy supports many O

Jan 4, 2023
Cache oci login token for kubectl

oci-token-cache Cache oci login token. This command cache oci login token into ~/.oci/token-cache.json and re-use for kubectl. Usage Currently, your ~

Nov 20, 2021
Lightweight SSO Login System

login Lightweight SSO Login System Convention Redirect to login.changkun.de?redirect=origin When login success, login.changkun.de will redirect to ori

Sep 29, 2022
Goauth: Pre-made OAuth/OpenIDConnect and general authorization hooks for webapp login

goauth Pre-made OAuth/OpenIDConnect and general authorization hooks for webapp login. Currently supports Google, Facebook and Microsoft "out of the bo

Jan 28, 2022