• No results found

Authentication with OAuth 2 using the Goth Package

In document Web Development with Go.pdf (Page 141-146)

The Go ecosystem provides various packages for working on the OAuth 2 authentication protocol. The Goth third-party package and its Gothic subpackage allow you to work with OAuth 2 providers. Goth supports OAuth 2 service providers such as LinkedIn, Facebook, Twitter, Google, and GitHub. The Goth package provides various providers to work with each service provider. For example, it provides the github.com/ markbates/goth/providers/twitter package for working with the Twitter identity provider.

To install the Goth package, run the following command in the terminal: go get github.com/markbates/goth

To work with the Goth package, you must add github.com/markbates/goth to the import list: import "github.com/markbates/goth"

Listing 7-1 is an example program that uses Twitter and Facebook as identity providers. In this program, Twitter and Facebook login credentials are used to authenticate into an example application.

Listing 7-1. Authentication with OAuth 2 Service Providers package main import ( "encoding/json" "fmt" "html/template" "log" "net/http" "os" "github.com/gorilla/pat" "github.com/markbates/goth" "github.com/markbates/goth/gothic" "github.com/markbates/goth/providers/facebook" "github.com/markbates/goth/providers/twitter" )

//Struct for parsing JSON configuration type Configuration struct {

TwitterKey string TwitterSecret string FacebookKey string FacebookSecret string }

var config Configuration

//Read configuration values from config.json func init() {

file, _ := os.Open("config.json") decoder := json.NewDecoder(file) config = Configuration{}

Chapter 7 ■ authentiCation to Web apps

if err != nil { log.Fatal(err) }

}

func callbackAuthHandler(res http.ResponseWriter, req *http.Request) { user, err := gothic.CompleteUserAuth(res, req)

if err != nil { fmt.Fprintln(res, err) return } t, _ := template.New("userinfo").Parse(userTemplate) t.Execute(res, user) }

func indexHandler(res http.ResponseWriter, req *http.Request) { t, _ := template.New("index").Parse(indexTemplate)

t.Execute(res, nil) }

func main() {

//Register providers with Goth goth.UseProviders(

twitter.New(config.TwitterKey, config.TwitterSecret, "http://localhost:8080/auth/ twitter/callback"),

facebook.New(config.FacebookKey, config.FacebookSecret, "http://localhost:8080/auth/ facebook/callback"),

)

//Routing using Pat package r := pat.New() r.Get("/auth/{provider}/callback", callbackAuthHandler) r.Get("/auth/{provider}", gothic.BeginAuthHandler) r.Get("/", indexHandler) server := &http.Server{ Addr: ":8080", Handler: r, } log.Println("Listening...") server.ListenAndServe() } //View templates var indexTemplate = `

<p><a href="/auth/twitter">Log in with Twitter</a></p> <p><a href="/auth/facebook">Log in with Facebook</a></p> `

var userTemplate = ` <p>Name: {{.Name}}</p> <p>Email: {{.Email}}</p> <p>NickName: {{.NickName}}</p>

Chapter 7 ■ authentiCation to Web apps

<p>Location: {{.Location}}</p>

<p>AvatarURL: {{.AvatarURL}} <img src="{{.AvatarURL}}"></p> <p>Description: {{.Description}}</p>

<p>UserID: {{.UserID}}</p>

<p>AccessToken: {{.AccessToken}}</p> `

Twitter and Facebook are used to log in to the example application. To do this, register the application with the corresponding identity provider. When you register an application with an identity provider, you get a client ID and secret key. Twitter and Facebook providers are registered with the Goth package by providing a client ID, client secret key, and callback URL.

After a successful login with an OAuth2 service provider, the server redirects to the callback URL: //Register OAuth2 providers with Goth

goth.UseProviders(

twitter.New(config.TwitterKey, config.TwitterSecret, "http://localhost:8080/auth/ twitter/callback"),

facebook.New(config.FacebookKey, config.FacebookSecret, "http://localhost:8080/auth/ facebook/callback"),

)

The client ID and client secret key are read from a configuration file in the init function.

Run the program and navigate to http://localhost:8080/. Figure 7-3 shows the home page of the application, which provides authentication with Twitter and Facebook.

Let’s choose Twitter to obtain access to the identity provider. It asks to authorize the application with Twitter account credentials, as shown in Figure 7-4.

Chapter 7 ■ authentiCation to Web apps

After a successful login with a social identity provider, the application is authorized to obtain access to the authentication server and gives user information to the application, including an access token and redirect to the callback URL that was provided when the social identity provider was registered with the Goth package.

Here is the application handler for the callback URL:

func callbackAuthHandler(res http.ResponseWriter, req *http.Request) { user, err := gothic.CompleteUserAuth(res, req)

if err != nil { fmt.Fprintln(res, err) return } t, _ := template.New("userinfo").Parse(userTemplate) t.Execute(res, user) }

When the CompleteUserAuth function of the Goth package is called, it returns a User struct of the Goth package. The User struct contains the information common to most OAuth and OAuth2 providers. All the “raw” data from the provider can be found in the RawData field.

Chapter 7 ■ authentiCation to Web apps

Here is the definition of User struct from the source of the Goth package: type User struct {

RawData map[string]interface{} Email string Name string NickName string Description string UserID string AvatarURL string Location string AccessToken string AccessTokenSecret string }

Finally, the view template is rendered by providing the User struct. Here is the view template used to render the UI to display user information:

var userTemplate = ` <p>Name: {{.Name}}</p> <p>Email: {{.Email}}</p> <p>NickName: {{.NickName}}</p> <p>Location: {{.Location}}</p>

<p>AvatarURL: {{.AvatarURL}} <img src="{{.AvatarURL}}"></p> <p>Description: {{.Description}}</p>

<p>UserID: {{.UserID}}</p>

<p>AccessToken: {{.AccessToken}}</p> `

Figure 7-5 shows the user information obtained from Twitter.

Chapter 7 ■ authentiCation to Web apps

In document Web Development with Go.pdf (Page 141-146)