Giter Site home page Giter Site logo

gauth's Introduction

GAuth

Software License Build Status GoDoc

Clean way to write authentication for Go.

This package was inspired by https://github.com/intridea/omniauth (written in Ruby) and http://github.com/markbates/goth (written in Go).

Features

  • Support both OAuth 1.0a and OAuth2
  • Have a long list of providers and is easy to write new ones.

Install

$ go get github.com/tamnd/gauth

List of Providers

Here are the list of supported providers. Would you love to see more providers? Feel free to contribute ones by create your own repository or create pull requests!

I use the list as reference. When porting providers directly from those gems, I also keep the author of the gems as author of the providers.

Please keep the list in alphabetical order

Provider Description Author Is Official?
AngelList Authenticate to AngelList using OAuth2. railsjedi No
Aol Authenticate to Aol using OAuth2. pianosnake No
App.net Authenticate to App.net using OAuth2. phuu No
Behance Authenticate to Behance using OAuth2. sandboxws No
Box Authenticate to Box using OAuth2. iCoreTech, Inc. No
Dropbox Authenticate to Dropbox using OAuth2. bamorim No
Facebook Authenticate to Facebook using OAuth2. tamnd No
Foursquare Authenticate to Foursquare using OAuth2. arunagw No
Instagram Authenticate to Instagram using OAuth2. tamnd No
Meetup Authenticate to Meetup using OAuth2. tapster No

Usage

First, import GAuth and create OAuth provider

import (
	"github.com/tamnd/gauth"
	"github.com/tamnd/gauth/provider/facebook"
)

// Create facebook provider
var provider = facebook.New("FACEBOOK_KEY", "FACEBOOK_CLIENT_SECRET", "http://localhost:8080/auth/facebook/callback")

Next, define a handler for GET /auth/facebook. This will redirect the user to the facebook login page.

func login(w http.ResponseWriter, r *http.Request) {
	authURL, _, err := provider.AuthURL("state")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	http.Redirect(w, r, authURL, http.StatusTemporaryRedirect)
}

Then define the handler for callback request at /auth/facebook/callback:

func callback(w http.ResponseWriter, r *http.Request) {
	code := r.URL.Query().Get("code")

	// Get access token from verification code.
	token, err := provider.Authorize(code)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Get the authenticating user
	user, err := provider.User(token)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Marshal user info and write to the response.
	output, _ := json.Marshal(user)
	w.Write([]byte(output))
}

Finally, we register those handlers and start the server:

func main() {
	fmt.Println("Start listening on :8080")

	http.Handle("/auth/facebook", http.HandlerFunc(login))
	http.Handle("/auth/facebook/callback", http.HandlerFunc(callback))
	http.ListenAndServe(":8080", nil)
}

See the full source code at examples/facebook.go.

Write new provider

Writing new provider is pretty easy. You just need to define OAuth endpoints:

package yoursite

import "github.com/tamnd/gauth/oauth2"

var Endpoint = oauth2.Endpoint{
	AuthURL:  "https://yoursite.com/oauth2/auth",
	TokenURL: "https://yoursite.com/oauth2/token",
}

and define a function User to get user info from an access token:

package yoursite

import "github.com/tamnd/gauth"

func User(token *gauth.AccessToken) (*gauth.User, error) {
	// Get the user info here...
}

For example, here is the Facebook Authentication Provider:

provider/facebook/facebook.go

package facebook

import (
	"github.com/tamnd/gauth"
	"github.com/tamnd/gauth/oauth2"
)

var Endpoint = oauth2.Endpoint{
	AuthURL:  "https://www.facebook.com/dialog/oauth",
	TokenURL: "https://graph.facebook.com/oauth/access_token",
}

func New(clientId string, secret string, callbackURL string, scopes ...string) gauth.Provider {
	provider := &oauth2.Provider{
		Endpoint: Endpoint,
		UserFn:   User,
	}
	provider.Init(clientId, secret, callbackURL)
	return provider
}

provider/facebook/user.go

package facebook

import (
	"net/url"

	"github.com/tamnd/gauth"
	"github.com/tamnd/httpclient"
)

var endpointProfile = "https://graph.facebook.com/me?fields=email,first_name,last_name,link,bio,id,name,picture,location"

func User(token *gauth.AccessToken) (*gauth.User, error) {
	URL := endpointProfile + "&access_token=" + url.QueryEscape(token.Token)

	u := struct {
		ID      string `json:"id"`
		Email   string `json:"email"`
		Bio     string `json:"bio"`
		Name    string `json:"name"`
		Link    string `json:"link"`
		Picture struct {
			Data struct {
				URL string `json:"url"`
			} `json:"data"`
		} `json:"picture"`
		Location struct {
			Name string `json:"name"`
		} `json:"location"`
	}{}

	err := httpclient.JSON(URL, &u)
	if err != nil {
		return nil, err
	}

	user := gauth.User{
		ID:          u.ID,
		Name:        u.Name,
		Email:       u.Email,
		Username:    u.Name,
		Location:    u.Location.Name,
		Description: u.Bio,
		Avatar:      u.Picture.Data.URL,
		Raw:         u,
	}

	return &user, nil
}

Contribute

  • Fork repository
  • Create a feature branch
  • Open a new pull request
  • Create an issue for bug report or feature request

Contact

License

The MIT License (MIT). Please see LICENSE for more information.

Copyright (c) 2015 Nguyen Duc Tam, [email protected]

gauth's People

Contributors

tamnd avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

gokrokvertskhov

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.