Golang接入Oauth2
ClearSky Drizzle Lv4

1. GitHub OAuth2

1.1 GitHub OAuth2 接入流程

在”Authorization callback URL”这里填写你的回调地址,可以是你的域名,也可以是你本地的回调地址,比如 http://localhost:8080/callback。相关配置填写之后,点击”Register application”创建即可。

image
应用创建完毕,会生成客户端 ID 和客户端密钥。客户端密钥需要单独生成,点击”Generate a new client secret”生成一个密钥即可。
image

1.2 GitHub OAuth2 接入代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main

import (
"context"
"encoding/json"
"fmt"
"io"
"log"
"net/http"

"golang.org/x/oauth2"
"golang.org/x/oauth2/github"
)

var (
githubOauthConfig = &oauth2.Config{
ClientID: "Ov23liHgJhetSUt45V9r",
ClientSecret: "ClientSecret", // 请替换为自己的ClientSecret
RedirectURL: "http://localhost:8080/callback",
Endpoint: github.Endpoint,
Scopes: []string{"user:email"},
}
oauthStateString = "random"
)

func main() {
http.HandleFunc("/", handleMain)
http.HandleFunc("/login", handleGitHubLogin)
http.HandleFunc("/callback", handleGitHubCallback)
http.HandleFunc("/logout", handleLogout)
log.Println("Started running on http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}

func handleMain(w http.ResponseWriter, r *http.Request) {
var htmlIndex = `<html><body><a href="/login">Log in with GitHub</a></body></html>`
io.WriteString(w, htmlIndex)
}

func handleGitHubLogin(w http.ResponseWriter, r *http.Request) {
url := githubOauthConfig.AuthCodeURL(oauthStateString)
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

type GitHubUser struct {
Login string `json:"login"`
ID int `json:"id"`
AvatarURL string `json:"avatar_url"`
HTMLURL string `json:"html_url"`
Name string `json:"name"`
Company string `json:"company"`
Blog string `json:"blog"`
Location string `json:"location"`
Email string `json:"email"`
Bio string `json:"bio"`
}

func handleGitHubCallback(w http.ResponseWriter, r *http.Request) {
if r.FormValue("state") != oauthStateString {
log.Println("invalid oauth state")
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}

token, err := githubOauthConfig.Exchange(context.Background(), r.FormValue("code"))
if err != nil {
log.Println("code exchange failed: ", err)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}

client := githubOauthConfig.Client(context.Background(), token)
resp, err := client.Get("https://api.github.com/user")
if err != nil {
log.Println("failed getting user info: ", err)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
defer resp.Body.Close()

var user GitHubUser
if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
log.Println("failed decoding response body: ", err)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}

// 格式化输出用户信息
fmt.Fprintf(w, `<html><body>
<h1>User Info</h1>
<p><strong>Login:</strong> %s</p>
<p><strong>ID:</strong> %d</p>
<p><strong>Avatar URL:</strong> <img src="%s" alt="avatar" ></p>
<p><strong>Profile URL:</strong> <a href="%s">%s</a></p>
<p><strong>Name:</strong> %s</p>
<p><strong>Company:</strong> %s</p>
<p><strong>Blog:</strong> %s</p>
<p><strong>Location:</strong> %s</p>
<p><strong>Email:</strong> %s</p>
<p><strong>Bio:</strong> %s</p>
</body></html>`,
user.Login,
user.ID,
user.AvatarURL,
user.HTMLURL, user.HTMLURL,
user.Name,
user.Company,
user.Blog,
user.Location,
user.Email,
user.Bio)
}

func handleLogout(w http.ResponseWriter, r *http.Request) {
// 清除会话cookie
http.SetCookie(w, &http.Cookie{
Name: "github_oauth_token",
Value: "",
Path: "/",
MaxAge: -1,
})
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}

1.3 授权登录

image
授权成功后,会跳转到回调地址,并返回授权码,然后通过授权码获取access_token,最后通过access_token获取用户信息。

image

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
This site is deployed on
Unique Visitor Page View