## 使用OAuth2 OAuth2是一种用于API通信的相对常见的协议。golang.org/x/oauth2 包提供了非常灵活的OAuth2操作,它的子包能为Facebook,Google和GitHub等各种提供商提供支持。 本节将演示如何为GitHub的搭建OAuth2和一些基本操作。 ### 实践 1. 获取支持库: ``` go get golang.org/x/oauth2 ``` [配置OAuth Client](https://github.com/settings/applications/new) 设置 Client ID and Secret: ``` 1. export GITHUB_CLIENT="your_client" 2. export GITHUB_SECRET="your_secret" ``` 可以在[https://developer.github.com/v3/](https://developer.github.com/v3/) 查看相关操作文档。 2. 建立 config.go: ``` package oauthcli import ( "context" "fmt" "os" "golang.org/x/oauth2" "golang.org/x/oauth2/github" ) // 设置oauth2.Config // 需要在环境变量中设置GITHUB_CLIENT GITHUB_SECRET func Setup() *oauth2.Config { return &oauth2.Config{ ClientID: os.Getenv("GITHUB_CLIENT"), ClientSecret: os.Getenv("GITHUB_SECRET"), Scopes: []string{"repo", "user"}, Endpoint: github.Endpoint, } } // GetToken 检索github oauth2令牌 func GetToken(ctx context.Context, conf *oauth2.Config) (*oauth2.Token, error) { url := conf.AuthCodeURL("state") fmt.Printf("Type the following url into your browser and follow the directions on screen: %v\n", url) fmt.Println("Paste the code returned in the redirect URL and hit Enter:") var code string if _, err := fmt.Scan(&code); err != nil { return nil, err } return conf.Exchange(ctx, code) } ``` 3. 建立 exec.go: ``` package oauthcli import ( "fmt" "io" "net/http" "os" ) // GetUsers 使用oauth2获取用户信息 func GetUsers(client *http.Client) error { url := fmt.Sprintf("https://api.github.com/user") resp, err := client.Get(url) if err != nil { return err } defer resp.Body.Close() fmt.Println("Status Code from", url, ":", resp.StatusCode) io.Copy(os.Stdout, resp.Body) return nil } ``` 4. 建立 main.go: ``` package main import ( "context" "github.com/agtorre/go-cookbook/chapter6/oauthcli" ) func main() { ctx := context.Background() conf := oauthcli.Setup() tok, err := oauthcli.GetToken(ctx, conf) if err != nil { panic(err) } client := conf.Client(ctx, tok) if err := oauthcli.GetUsers(client); err != nil { panic(err) } } ``` 5. 这会输出: ``` Visit the URL for the auth dialog: https://github.com/login/oauth/authorize? access_type=offline&client_id= <your_id>&response_type=code&scope=repo+user&state=state Paste the code returned in the redirect URL and hit Enter: <your_code> Status Code from https://api.github.com/user: 200 {<json_payload>} ``` ### 说明 标准OAuth2流是基于重定向的,会以服务器重定向到你指定的端点作为结束。然后你所在的端负责获取返回值并将其交换为令牌。示例通过允许我们使用诸如https://localhost 或https://a-domain-you-own 之类的URL并手动复制/粘贴代码然后按Enter键来绕过该要求。交换令牌后,客户端将根据需要自行刷新令牌。 重要的是要注意我们不以任何方式存储令牌。 如果程序崩溃,则必须重新交换令牌。同样要注意,除非刷新令牌过期,丢失或损坏,否则我们只需要显式检索一次令牌。配置客户端后,它应该能够为其授权的API执行所有典型的HTTP操作,并且具有适当的范围。 * * * * 学识浅薄,错误在所难免。欢迎在群中就本书提出修改意见,以飨后来者,长风拜谢。 Golang中国(211938256) beego实战(258969317) Go实践(386056972)