1. 程式人生 > >Go : OAuth2.0

Go : OAuth2.0

引用

引文以google為例子,這裡使用github為例子(訪問google有問題T_T)。

獲取 oauth2

$ go get golang.org/x/oauth2

如果出現錯誤(被牆?),請參直接使用github下載即可。

$ mkdir -p $GOPATH/src/golang.org/x
$ cd $GOPATH/src/golang.org/x
$ git clone https://github.com/golang/oauth2.git

建立client id

訪問這裡: https://github.com/settings/developers, 點選“New OAuth App”,示例配置如下:

Homepage URLhttp://localhost:8000/
Authorization callback URLhttp://localhost:8000/GithubCallback

建立成功後,會生產Client IDClient Secret

源程式

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"

    "golang.org/x/oauth2"
)

const htmlIndex = `<html><body>
<a href="/GithubLogin">Log in
with Github</a> </body></html> ` // Endpoint is Github's OAuth 2.0 endpoint. var endpoint = oauth2.Endpoint{ AuthURL: "https://github.com/login/oauth/authorize", TokenURL: "https://github.com/login/oauth/access_token", } var githubOauthConfig = &oauth2.Config{ ClientID: "YourClientID"
, ClientSecret: "YourClientSecret", RedirectURL: "http://localhost:8000/GithubCallback", Scopes: []string{"user", "repo"}, Endpoint: endpoint, } const oauthStateString = "random" func main() { http.HandleFunc("/", handleMain) http.HandleFunc("/GithubLogin", handleGithubLogin) http.HandleFunc("/GithubCallback", handleGithubCallback) fmt.Println(http.ListenAndServe(":8000", nil)) } func handleMain(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, htmlIndex) } func handleGithubLogin(w http.ResponseWriter, r *http.Request) { url := githubOauthConfig.AuthCodeURL(oauthStateString) fmt.Println(url) http.Redirect(w, r, url, http.StatusTemporaryRedirect) } func handleGithubCallback(w http.ResponseWriter, r *http.Request) { state := r.FormValue("state") if state != oauthStateString { fmt.Printf("invalid oauth state, expected '%s', got '%s'\n", oauthStateString, state) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return } fmt.Println(state) code := r.FormValue("code") fmt.Println(code) token, err := githubOauthConfig.Exchange(oauth2.NoContext, code) fmt.Println(token) if err != nil { fmt.Printf("Code exchange failed with '%s'\n", err) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return } response, err := http.Get("https://api.github.com/user?access_token=" + token.AccessToken) defer response.Body.Close() contents, err := ioutil.ReadAll(response.Body) fmt.Fprintf(w, "%s\n", contents) }

修改上面的 ClientIDClientSecret即可。