From f79e922fa0a5b5e04037a2d54fa1d91c36645bc2 Mon Sep 17 00:00:00 2001 From: rehjinh Date: Mon, 31 Jul 2023 12:43:02 +0900 Subject: [PATCH] =?UTF-8?q?SteamSDK=20-=20=EC=8A=A4=ED=8C=80=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20=EA=B4=80=EB=A0=A8=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/maingate.go | 7 +++ core/platformsteam.go | 127 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 core/platformsteam.go diff --git a/core/maingate.go b/core/maingate.go index f92977a..932189d 100644 --- a/core/maingate.go +++ b/core/maingate.go @@ -51,6 +51,7 @@ var ( ) const ( + AuthPlatformSteamSDK = "steam" AuthPlatformFirebaseAuth = "firebase" AuthPlatformGoogle = "google" AuthPlatformMicrosoft = "microsoft" @@ -139,6 +140,8 @@ type maingateConfig struct { GamepotProjectId string `json:"gamepot_project_id"` GamepotLoginCheckAPIURL string `json:"gamepot_logincheckapi_url"` FirebaseAdminSDKCredentialFile string `json:"firebase_admin_sdk_credentialfile"` + SteamAppId string `json:"steam_app_id"` + SteamPublisherAuthKey string `json:"steam_publisher_authkey"` } type globalAdmins struct { @@ -571,6 +574,8 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_get_login_url) serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_authorize_sdk) + serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformSteamSDK), mg.platform_steamsdk_authorize) + go mg.watchServiceCollection(ctx, serveMux, prefix) go mg.watchFileCollection(ctx, serveMux, prefix) // fsx := http.FileServer(http.Dir("console")) @@ -740,6 +745,8 @@ func (mg *Maingate) updateUserinfo(info usertokeninfo) (bool, string, string) { success, userid, email = mg.platform_microsoft_getuserinfo(info) case AuthPlatformGoogle: success, userid, email = mg.platform_google_getuserinfo(info) + case AuthPlatformSteamSDK: + success, userid, email = mg.platform_steamsdk_getuserinfo(info) case AuthPlatformFirebaseAuth: success, userid, email = mg.platform_firebase_getuserinfo(info) } diff --git a/core/platformsteam.go b/core/platformsteam.go new file mode 100644 index 0000000..4169af4 --- /dev/null +++ b/core/platformsteam.go @@ -0,0 +1,127 @@ +package core + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" + + "repositories.action2quare.com/ayo/gocommon/logger" +) + +type SteamSDKAuthInfo struct { + UserSteamId string `json:"steamid"` + UserAuthToken string `json:"authtoken"` +} + +func (mg *Maingate) platform_steamsdk_authorize(w http.ResponseWriter, r *http.Request) { + + defer r.Body.Close() + + brinfo, err := mg.GetUserBrowserInfo(r) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + logger.Error(err) + return + } + + var authinfo SteamSDKAuthInfo + + err = json.NewDecoder(r.Body).Decode(&authinfo) + if err != nil { + logger.Println("authinfo decoding fail:", err) + w.WriteHeader(http.StatusBadRequest) + return + } + + fmt.Println(authinfo) + + err = authenticateSteamUser(mg.SteamPublisherAuthKey, mg.SteamAppId, authinfo.UserSteamId, authinfo.UserAuthToken) + + if err == nil { + + acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix() + + var info usertokeninfo + info.platform = AuthPlatformSteamSDK + info.userid = authinfo.UserSteamId + info.token = authinfo.UserAuthToken + info.brinfo = brinfo + //info.accesstoken = respReferesh.AccessToken + info.accesstoken_expire_time = acceestoken_expire_time + mg.setUserToken(info) + + params := url.Values{} + params.Add("id", authinfo.UserSteamId) + params.Add("authtype", AuthPlatformSteamSDK) + w.Write([]byte("?" + params.Encode())) + //http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther) + } else { + logger.Println(err) + http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther) + } + +} + +func authenticateSteamUser(pubkey, appid, playerid, ticket string) error { + // Returns: The user's 64-bit SteamID if the user's ticket is valid + url := fmt.Sprintf("https://partner.steam-api.com/ISteamUserAuth/AuthenticateUserTicket/v1/?key=%s&appid=%s&ticket=%s", pubkey, appid, ticket) + resp, e := http.Get(url) + if e != nil { + return e + } + defer func() { + io.Copy(io.Discard, resp.Body) + resp.Body.Close() + }() + + body, e := ioutil.ReadAll(resp.Body) + if e != nil { + return e + } + + // fmt.Println(url) + // fmt.Println(string(body)) + + var doc map[string]interface{} + if err := json.Unmarshal(body, &doc); err != nil { + return err + } + + if v, ok := doc["response"]; ok { + response := v.(map[string]interface{}) + if v, ok = response["params"]; ok { + paramsnode := v.(map[string]interface{}) + if v, ok = paramsnode["result"]; ok { + if v.(string) == "OK" { + if v, ok = paramsnode["steamid"]; ok { + // playerid에는 빌드 구성 suffix가 붙어있는 상태이므로 == 비교가 아니라 HasPrefix로 비교 + if strings.HasPrefix(playerid, v.(string)) { + return nil + } + } + } else if v.(string) == "Invalid ticket" { + return errors.New("steam: invalid ticket") + } + } + } else if errdocraw, ok := response["error"]; ok { + errdoc := errdocraw.(map[string]interface{}) + desc := errdoc["errordesc"].(string) + return errors.New(desc) + } + } + return errors.New("steam: response is not expected") +} + +func (mg *Maingate) platform_steamsdk_getuserinfo(info usertokeninfo) (bool, string, string) { + + // Steam은 이메일 정보를 받을수 없기 때문에 dummy임시 주소 할당하여 리턴한다. + dummyEmail := fmt.Sprintf("__dummy_%s@steamtemp__", info.userid) + return true, info.userid, dummyEmail + +}