登录

Gin基于goth实现OAuth认证

Coding GooseForum
2025-08-12 18:33:59

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 不会授权认证的。

加入讨论

登录或注册以发表评论