feat: backend core - auth, user, role, permission, device, webhook, monitoring, cache, repository, service, middleware, API handlers
This commit is contained in:
233
internal/auth/oauth_config.go
Normal file
233
internal/auth/oauth_config.go
Normal file
@@ -0,0 +1,233 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user