google auth登录
准备
1.调试必须在远程服务端才可以,因为要用到回调系统,或者使用前端的转发工具才可以
2.在https://console.cloud.google.com/apis/dashboard
生成凭据>OAuth 2.0 客户端 ID,
3.设置凭据的回调地址,只能是域名,所以先要将域名解析到远程服务器(除非使用转发工具)
gin实现的简单demo
package main
import (
"context"
"encoding/json"
"log"
"net/http"
"github.com/gin-gonic/gin"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
var (
googleOauthConfig *oauth2.Config
oauthStateString = "random"
)
func init() {
googleOauthConfig = &oauth2.Config{
RedirectURL: "http://g.3kj.xyz/auth/google/callback", //回调地址
ClientID: "", //客户端id
ClientSecret: "", //客户端密钥
Scopes: []string{
"https://www.googleapis.com/auth/userinfo.email", //获取用户邮箱
},
Endpoint: google.Endpoint,
}
}
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*")
router.GET("/", func(c *gin.Context) {
log.Print("访问首页")
c.HTML(200, "index.html", nil)
})
router.GET("/googlelogin", handleGoogleLogin) //登录路由就是跳转路由
router.GET("/auth/google/callback", handleGoogleCallback) //回调路由
router.Run(":5280")
}
//登录函数跳转到
func handleGoogleLogin(c *gin.Context) {
url := googleOauthConfig.AuthCodeURL(oauthStateString)
c.Redirect(307, url)
}
//回调函数
func handleGoogleCallback(c *gin.Context) {
state := c.Request.FormValue("state")
if state != oauthStateString {
c.JSON(500, gin.H{"error": "state 不匹配"})
return
}
code := c.Request.FormValue("code")
token, err := googleOauthConfig.Exchange(context.Background(), code)
if err != nil {
c.JSON(500, gin.H{"error": "无法获取 token", "details": err.Error()})
return
}
response, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无法获取用户信息", "details": err.Error()})
return
}
defer response.Body.Close()
var userInfo struct {
Email string `json:"email"`
}
if err := json.NewDecoder(response.Body).Decode(&userInfo); err != nil {
c.JSON(500, gin.H{"error": "无法解析用户信息"})
return
}
log.Print("用户信息:",userInfo)
c.JSON(200, gin.H{"email": userInfo.Email})
}