Files
maingate/core/platformfirebaseauth.go

270 lines
7.0 KiB
Go
Raw Normal View History

2023-05-24 12:16:03 +09:00
package core
import (
"encoding/json"
"errors"
"log"
"net/http"
"net/url"
"time"
2023-05-24 15:31:01 +09:00
"repositories.action2quare.com/ayo/gocommon/logger"
2023-05-24 12:16:03 +09:00
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
func (mg *Maingate) platform_firebaseauth_get_login_url(w http.ResponseWriter, r *http.Request) {
browserinfo, err := mg.GetUserBrowserInfo(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
logger.Error(err)
return
}
existid := r.URL.Query().Get("existid")
withSDK := r.URL.Query().Get("withSDK")
// 무조껀 SDK 있어야됨
if withSDK != "1" {
return
}
//fmt.Println("existid =>", existid)
if existid != "" {
//기존 계정이 있는 경우에는 그 계정 부터 조회한다.
info, err := mg.getUserTokenWithCheck(AuthPlatformFirebaseAuth, existid, browserinfo)
if err == nil {
if info.token != "" {
params := url.Values{}
params.Add("id", existid)
params.Add("authtype", AuthPlatformFirebaseAuth)
if withSDK == "1" {
w.Write([]byte("?" + params.Encode()))
}
return
}
}
}
sessionkey := mg.GeneratePlatformLoginNonceKey()
nonce := mg.GeneratePlatformLoginNonceKey()
mg.mongoClient.Delete(CollectionPlatformLoginToken, bson.M{
"platform": AuthPlatformFirebaseAuth,
"key": sessionkey,
})
_, _, err = mg.mongoClient.Update(CollectionPlatformLoginToken, bson.M{
"_id": primitive.NewObjectID(),
}, bson.M{
"$setOnInsert": bson.M{
"platform": AuthPlatformFirebaseAuth,
"key": sessionkey,
"nonce": nonce,
"brinfo": browserinfo,
},
}, options.Update().SetUpsert(true))
if err != nil {
w.WriteHeader(http.StatusBadRequest)
logger.Error(err)
return
}
// set cookie for storing token
cookie := http.Cookie{
Name: "LoginFlowContext_SessionKey",
Value: sessionkey,
Expires: time.Now().Add(1 * time.Hour),
//SameSite: http.SameSiteStrictMode,
SameSite: http.SameSiteLaxMode,
// HttpOnly: false,
Secure: true,
Path: "/",
}
http.SetCookie(w, &cookie)
if withSDK == "1" {
params := url.Values{}
params.Add("nonce", nonce)
w.Write([]byte("?" + params.Encode()))
}
}
type FirebaseSDKAuthInfo struct {
MemberId string `json:"id"`
Code string `json:"code"`
State string `json:"state"`
Nickname string `json:"nickname"`
Provider string `json:"provider"`
ProviderId string `json:"providerId"`
Email string `json:"email"`
PhotoUrl string `json:"photourl"`
PhoneNumber string `json:"phonenumber"`
}
func (mg *Maingate) platform_firebaseauth_authorize_sdk(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
}
cookie, err := r.Cookie("LoginFlowContext_SessionKey")
if err != nil {
logger.Println("Session not found", err)
w.WriteHeader(http.StatusBadRequest)
return
}
var authinfo FirebaseSDKAuthInfo
err = json.NewDecoder(r.Body).Decode(&authinfo)
if err != nil {
logger.Println("authinfo decoding fail:", err)
w.WriteHeader(http.StatusBadRequest)
return
}
bSuccess, Result := mg.platform_firebaseauth_authorize_raw(w, brinfo, authinfo.Code, authinfo.State,
cookie.Value, authinfo.MemberId, authinfo.Nickname, authinfo.Provider, authinfo.ProviderId, authinfo.Email, authinfo.PhotoUrl, authinfo.PhoneNumber)
if bSuccess {
w.Write([]byte("?" + Result))
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
} else {
http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
}
}
func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, memberId, nickname, provider, providerId, email, photourl, phonenumber string) (bool, string) {
found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{
"platform": AuthPlatformFirebaseAuth,
"key": cookieSessionKey,
})
if err != nil {
logger.Println("LoginFlowContext_SessionKey find key :", err)
w.WriteHeader(http.StatusBadRequest)
return false, ""
}
if found == nil {
logger.Println("LoginFlowContext_SessionKey not found")
w.WriteHeader(http.StatusBadRequest)
return false, ""
}
if cookieSessionKey != found["key"] {
logger.Println("LoginFlowContext_SessionKey key not match")
logger.Println(cookieSessionKey)
logger.Println(found["key"])
w.WriteHeader(http.StatusBadRequest)
return false, ""
}
if state != found["nonce"] {
logger.Println("LoginFlowContext_SessionKey nonce not match")
logger.Println(state)
logger.Println(found["nonce"])
w.WriteHeader(http.StatusBadRequest)
return false, ""
}
if brinfo != found["brinfo"] { //-- 로그인 시작점과 인증점의 브라우저 혹은 접속지 정보가 다르다?
logger.Println("LoginFlowContext_SessionKey brinfo not match ")
logger.Println(brinfo)
logger.Println(found["brinfo"])
w.WriteHeader(http.StatusBadRequest)
return false, ""
}
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, code)
if err != nil {
log.Println("error verifying ID token:", err)
return false, ""
}
// log.Println("Verified ID token: ", token)
// log.Println("Verified ID token: ", token.UID)
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
if memberId != "" && provider != "" && providerId != "" {
var info usertokeninfo
info.platform = AuthPlatformFirebaseAuth
info.userid = memberId
info.token = code
info.brinfo = brinfo
info.accesstoken = ""
info.accesstoken_expire_time = acceestoken_expire_time
mg.setUserToken(info)
mg.mongoClient.Delete(CollectionFirebaseUserInfo, bson.M{
"firebaseuserid": info.userid,
})
_, _, err := mg.mongoClient.Update(CollectionFirebaseUserInfo, bson.M{
"_id": primitive.NewObjectID(),
}, bson.M{
"$setOnInsert": bson.M{
"firebaseuserid": memberId,
"firebasenickname": nickname,
"firebaseprovider": provider,
"firebaseproviderId": providerId,
"firebaseemail": email,
"firebasephotourl": photourl,
"firebasephonenumber": phonenumber,
"updatetime": time.Now(),
},
}, options.Update().SetUpsert(true))
if err != nil {
logger.Error(err)
}
params := url.Values{}
params.Add("id", memberId)
params.Add("authtype", AuthPlatformFirebaseAuth)
return true, params.Encode()
}
return false, ""
}
func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, string, string) {
found, err := mg.mongoClient.FindOne(CollectionFirebaseUserInfo, bson.M{
"firebaseuserid": info.userid,
})
if err != nil {
logger.Error(err)
return false, "", ""
}
if found == nil {
logger.Error(errors.New("firebase info not found: " + info.userid))
return false, "", ""
}
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, info.token)
if err != nil {
log.Println("error verifying ID token:", err)
return false, "", ""
}
tempEmail := found["firebaseemail"].(string)
return true, info.userid, tempEmail
}