Skip to main content

[WebApp] Protocal22-API 사용예제2

[WebApp] OwnerKey ApiProtocal22-API 사용예제2

시작하기 전에

이 문서는 Dabory OwnerKey API for WebApp을 사용해 main app과 guest app 개발시 필요한 참고 정보를 안내합니다.

 WebApp 사용예제

2. WebApp 사용 예제

📌 GateToken 발급 스케줄러 (Go)

package main
func main() {
    go func() {
		for {

			err := controllers_func.UpdateGateTokenIfNeeded()
			if err != nil {
				e.ErrLog("UpdateGateTokenIfNeeded Error", err)
			}
			time.Sleep(2 * time.Second)
		}

	}()
  }

📌 "OwnerKey"를 활용한 GateToken, BackUrl 반환 (Go)

Host의 dabory-app/gate-token-get을 호출 -> Host -> main_api (GateToken) 반환


func UpdateGateTokenIfNeeded() error {

	myOwnerKey := "My_OwnerKey"

	err := locals.GuestGateTokenGets(myOwnerKey)
	if err != nil {
		fmt.Println("GateToken 요청 실패:", err)
		return err
	}

	return nil
}


func GuestGateTokenGets(myOnwerKey string) error { 
	appType := 0 //Dbupdate
	// 0:keypair, 1:Dbu  // "SsoConnString" Must be Deprecated

	var err error

	if myOnwerKey != "" { 
		// e.LogStr("lskdjqfals", e.LogFuncName()+"; GuestGateTokenOwner with OwnerKey: "+myOnwerKey)
		_, _, err = GuestGateTokenOwner(appType, "https://host_domain_URL.com", myOnwerKey) // app type -> OwnerCode
		if err != nil {
			return e.ErrLog(e.FuncRun("23rfsr3qrase", e.CurrFuncName()), err)
		}
	} else {
		e.LogStr("lskdjqfals", e.LogFuncName()+"; GuestKeyPairGet without OwnerKey ")
		_, _, err = GuestGateTokenGet(appType, abango.XConfig["SsoConnString"], abango.XConfig["SsoAppBase64"])
		if err != nil {
			return e.ErrLog(e.FuncRun("23rfsr3qre", e.CurrFuncName()), err)
		}

	}

	return err
}

func GuestGateTokenOwner(appType int, pivotUrl string, ownerKey string) (string, string, error) { // HOST URL/dabory-app ->  pivot URL
	var appTypeCode string
	if appType == 0 {
		appTypeCode = "keypair"
	} else if appType == 1 {
		appTypeCode = "dbupdate"
	}

	if GAppApis[appType].GateToken != "" { // 할당되어 있는 경우
		// fmt.Println("34092ujfa : "+"Using GateToken in ARRAY to access : ", GAppApis[0].GateToken)
	} else {
		fmt.Println("34092ujfa : " + "isn't exist GateToken in ARRAY to access ")

		vGt := &GateTokenGetReq{
			OwnerKey: ownerKey,
		}
		bodyBytes, _ := json.Marshal(vGt)

		frontUrl := pivotUrl + "/dabory-app/gate-token-get"
		msgBytes, staInt, err := HttpResponseSimplePost("POST", frontUrl, bodyBytes)
		e.LogStr("23rfsr3qr-GateTokenGetReq", e.LogFuncName()+";  Raravel frontUrl : "+frontUrl)
		if err != nil {
			return "", "", e.ErrLog(e.FuncRun("45425fd34sd-The HTTP request "+frontUrl, e.CurrFuncName()), err)
		}

		if staInt != 200 {
			TrackFailure() // 요청 실패 시 실패 기록 추가
			fmt.Println("GateToken 요청 실패:", err, "(최근 1시간 내 실패 횟수:", len(failTimestamps), ")", "반환 Code : ", staInt)

			// 최근 1시간 동안 실패 횟수가 maxFailures(3) 이상이면 프로그램 종료
			if len(failTimestamps) >= maxFailures {
				fmt.Println("1시간 내 GateToken 요청이", maxFailures, "번 실패 -> 스케줄러를 종료")
				os.Exit(1) // 프로그램 종료
			}

			return "", "", errors.New(e.FuncRun("87ty344ra3-Request Fail "+string(msgBytes), e.CurrFuncName()))
		}

		failTimestamps = []int64{} // 실패 기록 초기화

		ret := &struct {
			ApiUrl    string // 비부분이 실제 Host의 .env.dabory 에서 Backend API Url이다
			GateToken string
		}{}

		if err := json.Unmarshal(msgBytes, ret); err != nil {
			return "", "", e.ErrLog(e.FuncRun("45425fd34sd-Json Format "+frontUrl, e.CurrFuncName()), err)
		}
		GAppApis[appType].ApiUrl = ret.ApiUrl
		GAppApis[appType].GateToken = ret.GateToken
		e.OkLog("Just Added GateToken in ARRAY to access AppType: " + appTypeCode)
		e.OkLog("Just Added GateToken in ARRAY to access AppType: " + ret.GateToken)
		e.OkLog("Just Added GateToken in ARRAY to access AppType: " + ret.ApiUrl) // main_api URL

	}
	return GAppApis[appType].ApiUrl, GAppApis[appType].GateToken, nil
}

📌 발급받은 GateToken을 사용하여 main_api 요청 (Go)



func process() {
apiUrl := locals.GAppApis[0].ApiUrl
gateToken := locals.GAppApis[0].GateToken


		mainApiURL := apiUrl + "/credit-page"
		requestBody := map[string]interface{}{
			"PageVars": map[string]interface{}{
				"Fields":     "credit_no",
				"Limit":      2,
				"Desc":       "id",
				"MyFilter":   "",
				"QueryCnt":   0,
				"Query":      "",
				"Asc":        "",
				"Offset":     0,
				"ReturnJson": "",
			},
		}
		Body, err := RequestWithGateToken(mainApiURL, gateToken, requestBody)
		if err != nil {
			e.ErrLog("Error : ", err)
		}
}

📌 저장된 GateToken으로 요청 (만료된 GateToken 재 발급)


func RequestWithGateToken(mainApiURL string, gateToken string, requestBody map[string]interface{}) ([]byte, error) {
  resp, body, err := SendHttpRequest(mainApiURL, gateToken, requestBody)
    if err != nil {
    fmt.Println("HTTP 요청 실패", err)
      return nil, err
  }


    defer resp.Body.Close()


    fmt.Println("body : ", string(body))


  if resp.StatusCode == 505 {
    fmt.Println("GateToken 만료 재발급 시도..")
    locals.GAppApis[0] = locals.AppApi{} // 기존 만료된 GateToken 배열에서 삭제


    for locals.GAppApis[0].GateToken == "" {
      fmt.Println("GateToken 발급 중..")
      time.Sleep(5 * time.Second)
  }


    fmt.Println("새로운 GateToken 발급 완료")


    newGateToken := locals.GAppApis[0].GateToken
    newMainApiURL := mainApiURL


      resp, body, err := SendHttpRequest(newMainApiURL, newGateToken, requestBody)
    if err != nil {
      fmt.Println("HTTP 요청 실패", err)
      return nil, err
  }
    defer resp.Body.Close()


    if err != nil {
      fmt.Println("새로운 응답 본문 읽기 실패:", err)
      return nil, err
  }


    if resp.StatusCode == 200 {
      e.OkLog("Success to HTTP Request through New GateToken")
      return body, nil
    } else {
      return nil, fmt.Errorf("새로운 GateToken 요청 실패, 상태 코드: %d", resp.StatusCode)
  }
}


    e.OkLog("Success to HTTP Request through previous GateToken")


    return body, nil
}




func SendHttpRequest(mainApiURL string, gateToken string, requestBody map[string]interface{}) (*http.Response, []byte, error) {

	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		fmt.Println("Json 변환 실패", err)
		return nil, nil, err
	}

	req, err := http.NewRequest("POST", mainApiURL, bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Println("HTTP 요청 생성 실패:", err)
		return nil, nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("GateToken", gateToken)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("HTTP 요청 실패", err)
		return nil, nil, err
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Response return failed", err)
		return nil, nil, err
	}
	fmt.Println("응답 코드 : ", resp.StatusCode)
	fmt.Println("응답 본문 : ", string(body))
	return resp, body, nil

}