Files

234 lines
7.5 KiB
Go
Raw Permalink Normal View History

package auth
import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"gopkg.in/yaml.v3"
)
// OAuthConfigYAML OAuth配置结构 (从YAML文件加载)
type OAuthConfigYAML struct {
Common CommonConfig `yaml:"common"`
WeChat WeChatOAuthConfig `yaml:"wechat"`
Google GoogleOAuthConfig `yaml:"google"`
Facebook FacebookOAuthConfig `yaml:"facebook"`
QQ QQOAuthConfig `yaml:"qq"`
Weibo WeiboOAuthConfig `yaml:"weibo"`
Twitter TwitterOAuthConfig `yaml:"twitter"`
}
// CommonConfig 通用配置
type CommonConfig struct {
RedirectBaseURL string `yaml:"redirect_base_url"`
CallbackPath string `yaml:"callback_path"`
}
// WeChatOAuthConfig 微信OAuth配置
type WeChatOAuthConfig struct {
Enabled bool `yaml:"enabled"`
AppID string `yaml:"app_id"`
AppSecret string `yaml:"app_secret"`
Scopes []string `yaml:"scopes"`
AuthURL string `yaml:"auth_url"`
TokenURL string `yaml:"token_url"`
UserInfoURL string `yaml:"user_info_url"`
MiniProgram MiniProgramConfig `yaml:"mini_program"`
}
// MiniProgramConfig 小程序配置
type MiniProgramConfig struct {
Enabled bool `yaml:"enabled"`
AppID string `yaml:"app_id"`
AppSecret string `yaml:"app_secret"`
}
// GoogleOAuthConfig Google OAuth配置
type GoogleOAuthConfig struct {
Enabled bool `yaml:"enabled"`
ClientID string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"`
Scopes []string `yaml:"scopes"`
AuthURL string `yaml:"auth_url"`
TokenURL string `yaml:"token_url"`
UserInfoURL string `yaml:"user_info_url"`
JWTAuthURL string `yaml:"jwt_auth_url"`
}
// FacebookOAuthConfig Facebook OAuth配置
type FacebookOAuthConfig struct {
Enabled bool `yaml:"enabled"`
AppID string `yaml:"app_id"`
AppSecret string `yaml:"app_secret"`
Scopes []string `yaml:"scopes"`
AuthURL string `yaml:"auth_url"`
TokenURL string `yaml:"token_url"`
UserInfoURL string `yaml:"user_info_url"`
}
// QQOAuthConfig QQ OAuth配置
type QQOAuthConfig struct {
Enabled bool `yaml:"enabled"`
AppID string `yaml:"app_id"`
AppKey string `yaml:"app_key"`
AppSecret string `yaml:"app_secret"`
RedirectURI string `yaml:"redirect_uri"`
Scopes []string `yaml:"scopes"`
AuthURL string `yaml:"auth_url"`
TokenURL string `yaml:"token_url"`
OpenIDURL string `yaml:"openid_url"`
UserInfoURL string `yaml:"user_info_url"`
}
// WeiboOAuthConfig 微博OAuth配置
type WeiboOAuthConfig struct {
Enabled bool `yaml:"enabled"`
AppKey string `yaml:"app_key"`
AppSecret string `yaml:"app_secret"`
RedirectURI string `yaml:"redirect_uri"`
Scopes []string `yaml:"scopes"`
AuthURL string `yaml:"auth_url"`
TokenURL string `yaml:"token_url"`
UserInfoURL string `yaml:"user_info_url"`
}
// TwitterOAuthConfig Twitter OAuth配置
type TwitterOAuthConfig struct {
Enabled bool `yaml:"enabled"`
ClientID string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"`
Scopes []string `yaml:"scopes"`
AuthURL string `yaml:"auth_url"`
TokenURL string `yaml:"token_url"`
UserInfoURL string `yaml:"user_info_url"`
}
var (
oauthConfig *OAuthConfigYAML
oauthConfigOnce sync.Once
)
// LoadOAuthConfig 加载OAuth配置
func LoadOAuthConfig(configPath string) (*OAuthConfigYAML, error) {
var err error
oauthConfigOnce.Do(func() {
// 如果未指定配置文件,尝试默认路径
if configPath == "" {
configPath = filepath.Join("configs", "oauth_config.yaml")
}
// 如果配置文件不存在,尝试从环境变量加载
if _, statErr := os.Stat(configPath); os.IsNotExist(statErr) {
oauthConfig = loadFromEnv()
return
}
// 从文件加载配置
data, readErr := os.ReadFile(configPath)
if readErr != nil {
oauthConfig = loadFromEnv()
err = fmt.Errorf("failed to read oauth config file: %w", readErr)
return
}
oauthConfig = &OAuthConfigYAML{}
if unmarshalErr := yaml.Unmarshal(data, oauthConfig); unmarshalErr != nil {
oauthConfig = loadFromEnv()
err = fmt.Errorf("failed to parse oauth config file: %w", unmarshalErr)
return
}
})
return oauthConfig, err
}
// loadFromEnv 从环境变量加载配置
func loadFromEnv() *OAuthConfigYAML {
return &OAuthConfigYAML{
Common: CommonConfig{
RedirectBaseURL: getEnv("OAUTH_REDIRECT_BASE_URL", "http://localhost:8080"),
CallbackPath: getEnv("OAUTH_CALLBACK_PATH", "/api/v1/auth/oauth/callback"),
},
WeChat: WeChatOAuthConfig{
Enabled: getEnvBool("WECHAT_OAUTH_ENABLED", false),
AppID: getEnv("WECHAT_APP_ID", ""),
AppSecret: getEnv("WECHAT_APP_SECRET", ""),
AuthURL: "https://open.weixin.qq.com/connect/qrconnect",
TokenURL: "https://api.weixin.qq.com/sns/oauth2/access_token",
UserInfoURL: "https://api.weixin.qq.com/sns/userinfo",
},
Google: GoogleOAuthConfig{
Enabled: getEnvBool("GOOGLE_OAUTH_ENABLED", false),
ClientID: getEnv("GOOGLE_CLIENT_ID", ""),
ClientSecret: getEnv("GOOGLE_CLIENT_SECRET", ""),
AuthURL: "https://accounts.google.com/o/oauth2/v2/auth",
TokenURL: "https://oauth2.googleapis.com/token",
UserInfoURL: "https://www.googleapis.com/oauth2/v2/userinfo",
JWTAuthURL: "https://oauth2.googleapis.com/tokeninfo",
},
Facebook: FacebookOAuthConfig{
Enabled: getEnvBool("FACEBOOK_OAUTH_ENABLED", false),
AppID: getEnv("FACEBOOK_APP_ID", ""),
AppSecret: getEnv("FACEBOOK_APP_SECRET", ""),
AuthURL: "https://www.facebook.com/v18.0/dialog/oauth",
TokenURL: "https://graph.facebook.com/v18.0/oauth/access_token",
UserInfoURL: "https://graph.facebook.com/v18.0/me?fields=id,name,email,picture",
},
QQ: QQOAuthConfig{
Enabled: getEnvBool("QQ_OAUTH_ENABLED", false),
AppID: getEnv("QQ_APP_ID", ""),
AppKey: getEnv("QQ_APP_KEY", ""),
AppSecret: getEnv("QQ_APP_SECRET", ""),
RedirectURI: getEnv("QQ_REDIRECT_URI", ""),
AuthURL: "https://graph.qq.com/oauth2.0/authorize",
TokenURL: "https://graph.qq.com/oauth2.0/token",
OpenIDURL: "https://graph.qq.com/oauth2.0/me",
UserInfoURL: "https://graph.qq.com/user/get_user_info",
},
Weibo: WeiboOAuthConfig{
Enabled: getEnvBool("WEIBO_OAUTH_ENABLED", false),
AppKey: getEnv("WEIBO_APP_KEY", ""),
AppSecret: getEnv("WEIBO_APP_SECRET", ""),
RedirectURI: getEnv("WEIBO_REDIRECT_URI", ""),
AuthURL: "https://api.weibo.com/oauth2/authorize",
TokenURL: "https://api.weibo.com/oauth2/access_token",
UserInfoURL: "https://api.weibo.com/2/users/show.json",
},
Twitter: TwitterOAuthConfig{
Enabled: getEnvBool("TWITTER_OAUTH_ENABLED", false),
ClientID: getEnv("TWITTER_CLIENT_ID", ""),
ClientSecret: getEnv("TWITTER_CLIENT_SECRET", ""),
AuthURL: "https://twitter.com/i/oauth2/authorize",
TokenURL: "https://api.twitter.com/2/oauth2/token",
UserInfoURL: "https://api.twitter.com/2/users/me",
},
}
}
// GetOAuthConfig 获取OAuth配置
func GetOAuthConfig() *OAuthConfigYAML {
if oauthConfig == nil {
_, _ = LoadOAuthConfig("")
}
return oauthConfig
}
// getEnv 获取环境变量
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
// getEnvBool 获取布尔型环境变量
func getEnvBool(key string, defaultValue bool) bool {
if value := os.Getenv(key); value != "" {
return strings.ToLower(value) == "true" || value == "1"
}
return defaultValue
}