Go every day a library of goth

darjun
中文

Introduction

Currently, many websites directly use third-party authentication to log in, such as Alipay/WeChat/Github, etc. goth encapsulates the method of accessing third-party authentication, and implements many third-party authentication implementations built-in:

goth figure is only part of the support of 0610751a93db6b. The complete list can be on its 1610751a93db98 GitHub homepage .

Quick to use

The code in this article uses Go Modules.

Create a directory and initialize:

$ mkdir goth && cd goth
$ go mod init github.com/darjun/go-daily-lib/goth

Install the goth library:

$ go get -u github.com/markbates/goth

We have designed two pages, a login page:

// login.tpl
<a href="/auth/github?provider=github">Login With GitHub</a>

Clicking on the login link will request /auth/github?provider=github .

A main interface:

// home.tpl
<p><a href="/logout/github">logout</a></p>
<p>Name: {{.Name}} [{{.LastName}}, {{.FirstName}}]</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>
<p>ExpiresAt: {{.ExpiresAt}}</p>
<p>RefreshToken: {{.RefreshToken}}</p>

Display the basic information of the user.

Similarly, we use the html/template standard template library to load and manage page templates:

var (
  ptTemplate *template.Template
)

func init() {
  ptTemplate = template.Must(template.New("").ParseGlob("tpls/*.tpl"))
}

The main page is processed as follows:

func HomeHandler(w http.ResponseWriter, r *http.Request) {
  user, err := gothic.CompleteUserAuth(w, r)
  if err != nil {
    http.Redirect(w, r, "/login/github", http.StatusTemporaryRedirect)
    return
  }
  ptTemplate.ExecuteTemplate(w, "home.tpl", user)
}

If the user logs in, gothic.CompleteUserAuth(w, r) will return a non-empty User object, which has the following fields:

type User struct {
  RawData           map[string]interface{}
  Provider          string
  Email             string
  Name              string
  FirstName         string
  LastName          string
  NickName          string
  Description       string
  UserID            string
  AvatarURL         string
  Location          string
  AccessToken       string
  AccessTokenSecret string
  RefreshToken      string
  ExpiresAt         time.Time
  IDToken           string
}

If logged in, the main interface information is displayed. If you are not logged in, redirect to the login interface:

func LoginHandler(w http.ResponseWriter, r *http.Request) {
  ptTemplate.ExecuteTemplate(w, "login.tpl", nil)
}

Click to log in, and the request AuthHandler

func AuthHandler(w http.ResponseWriter, r *http.Request) {
  gothic.BeginAuthHandler(w, r)
}

Call gothic.BeginAuthHandler(w, r) start jumping to the GitHub verification interface. After GitHub verification is complete, the browser will be redirected to /auth/github/callback processing:

func CallbackHandler(w http.ResponseWriter, r *http.Request) {
  user, err := gothic.CompleteUserAuth(w, r)
  if err != nil {
    fmt.Fprintln(w, err)
    return
  }
  ptTemplate.ExecuteTemplate(w, "home.tpl", user)
}

If the login is successful, in CallbackHandler , we can call gothic.CompleteUserAuth(w, r) retrieve the User object, and then display the main page. Finally, the message routing settings:

r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
r.HandleFunc("/login/github", LoginHandler)
r.HandleFunc("/logout/github", LogoutHandler)
r.HandleFunc("/auth/github", AuthHandler)
r.HandleFunc("/auth/github/callback", CallbackHandler)

log.Println("listening on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", r))

goth encapsulates the GitHub verification process for us, but we need to add an OAuth App on GitHub to generate Client ID and Client Secret.

First, log in to your GitHub account and select Settings in the drop-down box of the avatar on the right:

Select Developer Settings on the left:

Select OAuth App on the left, and click New OAuth App on the right:

Enter the information, the focus is Authorization callback URL , this is the callback after successful GitHub verification:

After the App is generated, the Client ID will be automatically generated, but the Client Secret needs to be generated by Generate a new client token

The Client Secret is generated:

To use Github in your program, you must first create a GitHub Provider and call New() method of the github sub-package:

githubProvider := github.New(clientKey, clientSecret, "http://localhost:8080/auth/github/callback")

The first parameter is the Client ID, the second parameter is the Client Secret, these two are generated by the OAuth App above, and the third parameter is the callback link, which must be the same as the one set when the OAuth App was created.

Then apply this Provider:

goth.UseProviders(githubProvider)

After the preparations are complete, he sighs. Now run the program:

$ SECRET_KEY="secret" go run main.go

The browser visits localhost:8080 , and because there is no login, it is redirected to localhost:8080/login/github :

Click Login with GitHub and you will be redirected to the GitHub authorization page:

Click Authorize, user information will be saved in session after success
middle. Jump to the main page and display my information:

Replace store

goth gorilla/sessions library introduced in the previous article to store login information, and cookies are used as storage by default. In addition, the options are used by default:

&Options{
  Path:   "/",
  Domain: "",
  MaxAge: 86400 * 30,
  HttpOnly: true,
  Secure: false,
}

If you need to change the storage method or options, we can set the gothic.Store field before the program starts. For example, we want to change to redistore:

store, _ = redistore.NewRediStore(10, "tcp", ":6379", "", []byte("redis-key"))

key := ""
maxAge := 86400 * 30  // 30 days
isProd := false

store := sessions.NewCookieStore([]byte(key))
store.MaxAge(maxAge)
store.Options.Path = "/"
store.Options.HttpOnly = true
store.Options.Secure = isProd

gothic.Store = store

Summarize

If you find a fun and useful Go language library, welcome to submit an issue on the Go Daily Library GitHub😄

refer to

  1. goth GitHub:github.com/markbates/goth
  2. Go daily library GitHub: https://github.com/darjun/go-daily-lib

I

My blog: https://darjun.github.io

Welcome to follow my WeChat public account [GoUpUp], learn together and make progress together~

阅读 647

深入理解Go
深入理解go中的点点滴滴
2.7k 声望
211 粉丝
0 条评论
你知道吗?

2.7k 声望
211 粉丝
宣传栏