283 lines
7.5 KiB
Go
283 lines
7.5 KiB
Go
package core
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
|
|
|
"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) {
|
|
if mg.firebase == nil {
|
|
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return false, ""
|
|
}
|
|
|
|
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.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.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) {
|
|
if mg.firebase == nil {
|
|
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
|
|
return false, "", ""
|
|
}
|
|
|
|
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.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, info.token)
|
|
if err != nil {
|
|
log.Println("error verifying ID token:", err)
|
|
return false, "", ""
|
|
}
|
|
|
|
tempEmail := found["firebaseemail"].(string)
|
|
if found["firebaseprovider"].(string) == "guest" {
|
|
tempEmail = fmt.Sprintf("%s@guest.flag", info.userid)
|
|
}
|
|
|
|
return true, info.userid, tempEmail
|
|
|
|
}
|