Gin基于goth实现OAuth认证(实现github 登陆自己的站点)
也欢迎大家来 GooseForum 体验一下实现效果
Goth 是一个 golang 身份验证 Go Web 应用程序的包。 内置了许多站点的 oauth 的接入方式。 官网有提供 example 代码。
这里单独提一下 gin 的接入方式 。
初始化
var store *sessions.CookieStore
// InitOAuth 初始化OAuth配置
func InitOAuth() {
// 初始化session store
secretKey := preferences.GetString("app.signingKey", algorithm.SafeGenerateSigningKey(32))
store = sessions.NewCookieStore([]byte(secretKey))
// 设置goth的session store
gothic.Store = store
// 初始化所有配置的OAuth提供商
var providers []goth.Provider
// 配置GitHub OAuth
if provider := initGitHubProvider(); provider != nil {
providers = append(providers, provider)
}
// 初始化其他OAuth提供商
if provider := initGoogleProvider(); provider != nil {
providers = append(providers, provider)
}
if len(providers) > 0 {
goth.UseProviders(providers...)
slog.Info("OAuth提供商初始化完成", "count", len(providers))
} else {
slog.Warn("未配置任何OAuth提供商")
}
}
// initGitHubProvider 初始化GitHub OAuth提供商
func initGitHubProvider() goth.Provider {
clientID := preferences.GetString("github.client_id", "")
clientSecret := preferences.GetString("github.client_secret", "")
callbackURL := hotdataserve.GetSiteSettingsConfigCache().SiteUrl + "/api/auth/github/callback"
if clientID == "" || clientSecret == "" {
slog.Warn("GitHub OAuth配置缺失,跳过初始化")
return nil
}
slog.Info("GitHub OAuth提供商初始化完成")
return github.New(clientID, clientSecret, callbackURL)
}
// initGoogleProvider 初始化Google OAuth提供商
func initGoogleProvider() *google.Provider {
clientID := preferences.GetString("google.client_id")
clientSecret := preferences.GetString("google.client_secret")
callbackURL := hotdataserve.GetSiteSettingsConfigCache().SiteUrl + "/api/auth/google/callback"
if clientID != "" && clientSecret != "" && callbackURL != "" {
// goth.UseProviders(googleProvider)
slog.Info("Google OAuth provider configuration found (implementation pending)")
}
return google.New(clientID, clientSecret, callbackURL)
}
接口封装
官网的例子是基于 github.com/gorilla
我们这里采用的是 gin 所以要注意 provider的设置方式,
路由
baseApi.GET("auth/:provider", controllers.ProviderLogin) // 发起认证,goth封装了重定向相关的逻辑
baseApi.GET("auth/:provider/callback", middleware.JWTAuthCheck, controllers.ProviderCallback) // 回调地址。
接口和回调
// ProviderLogin 开始OAuth登录/绑定流程(根据登录状态自动判断)
func ProviderLogin(c *gin.Context) {
q := c.Request.URL.Query()
q.Add("provider", c.Param("provider"))
c.Request.URL.RawQuery = q.Encode()
// 开始OAuth流程
gothic.BeginAuthHandler(c.Writer, c.Request)
}
// ProviderCallback 处理OAuth登录/绑定回调(根据登录状态自动判断)
func ProviderCallback(c *gin.Context) {
q := c.Request.URL.Query()
q.Add("provider", c.Param("provider"))
c.Request.URL.RawQuery = q.Encode()
// 完成OAuth流程
gothUser, err := gothic.CompleteUserAuth(c.Writer, c.Request)
if err != nil {
slog.Error("OAuth callback failed", "error", err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "OAuth认证失败",
})
return
}
// logic ....
}
Github 接入
注意 Request user authorization (OAuth) during installation
一定要勾选,否则 github 不会授权认证的。
本作品采用《CC 协议》,转载必须注明作者和本文链接
power by GooseForum
推荐文章: