服务端实现
- 从OAuth2库导入相关的包:
import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
- 定义OAuth2认证的配置:
var (
googleOauthConfig *oauth2.Config
oauthStateString = "random_string"
)
func init() {
googleOauthConfig = &oauth2.Config{
RedirectURL: "http://localhost:8080/oauth2callback",
ClientID: "<client_id>",
ClientSecret: "<client_secret>",
Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile"},
Endpoint: google.Endpoint,
}
}
- 编写HTTP处理程序:
func HandleHome(w http.ResponseWriter, r *http.Request) {
var html = `
<html>
<body>
<a href="%s">Google Login</a>
</body>
</html>
`
fmt.Fprintf(w, html, GetLoginURL(oauthStateString))
}
func GetLoginURL(state string) string {
return googleOauthConfig.AuthCodeURL(state)
}
func HandleOAuth2Callback(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
}
code := r.FormValue("code")
token, err := googleOauthConfig.Exchange(oauth2.NoContext, code)
if err != nil {
fmt.Printf("oauth2: %s", err.Error())
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
client := googleOauthConfig.Client(oauth2.NoContext, token)
resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo")
if err != nil {
fmt.Printf("Get: %s", err.Error())
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("ReadAll: %s", err.Error())
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
fmt.Fprintf(w, "Content: %s\n", contents)
}
- 启动服务端监听:
http.HandleFunc("/", HandleHome)
http.HandleFunc("/oauth2callback", HandleOAuth2Callback)
http.ListenAndServe(":8080", nil)
客户端实现
- 创建OAuth2配置:
var (
googleOauthConfig *oauth2.Config
)
func init() {
googleOauthConfig = &oauth2.Config{
ClientID: "<client_id>",
ClientSecret: "<client_secret>",
RedirectURL: "http://localhost:9000/oauth2callback",
Scopes: []string{
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile",
},
Endpoint: google.Endpoint,
}
}
- 发起OAuth2授权请求:
func HandleGoogleLogin(w http.ResponseWriter, r *http.Request) {
url := googleOauthConfig.AuthCodeURL("state")
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}
- 处理OAuth2回调:
func HandleGoogleCallback(w http.ResponseWriter, r *http.Request) {
code := r.FormValue("code")
token, err := googleOauthConfig.Exchange(oauth2.NoContext, code)
if err != nil {
fmt.Fprintln(w, err)
return
}
client := googleOauthConfig.Client(oauth2.NoContext, token)
resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo")
if err != nil {
fmt.Fprintln(w, err)
return
}
defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)
fmt.Fprintf(w, "Content: %s\n", contents)
}
启动客户端:
http.HandleFunc("/login/google", HandleGoogleLogin)
http.HandleFunc("/oauth2callback", HandleGoogleCallback)
log.Fatal(http.ListenAndServe(":9000", nil))