기록일지

2022-01-12

원클릭쓰리버그 2022. 1. 13. 10:37
728x90

Cognito UI 호스트 연결하기.

한동안 고민 끝에 드디어 소셜로그인을 통해 Userpool에 연결에 성공하였다.

정리하여 올릴 예정이지만 간단히 적어 놓도록 하자.

 

참고한 동영상은 이다.

https://www.youtube.com/watch?v=lzQ2rLqlqyk&t=722s

영상의 github 링크는 

https://github.com/BatteryAcid/unity-cognito-hostedui-social-client

 

GitHub - BatteryAcid/unity-cognito-hostedui-social-client: This project is a Unity client that demonstrates how to use AWS Cogni

This project is a Unity client that demonstrates how to use AWS Cognito's hosted UI to authenticate with social identity providers (like Google, Facebook, etc) as well as typical username and p...

github.com

 

흐름을 이야기하면 

1. userpool를 설정한다.

2. Unity를 통해 설정한 UI에 접근한다. 

3. UI접근하여 Google 로그인 후 토큰을 받는다.

 

1. Userpool 설정

참고 문서

https://docs.aws.amazon.com/ko_kr/cognito/latest/developerguide/cognito-user-pools-social-idp.html

 

사용자 풀에 소셜 자격 증명 공급자 추가 - Amazon Cognito

사용자 풀에 소셜 자격 증명 공급자 추가 웹 및 모바일 앱 사용자들이 Facebook, Google, Amazon 및 Apple 같은 소셜 자격 증명 공급자(IdP)를 통해 로그인할 수 있습니다. Amazon Cognito는 내장된 호스트 웹 UI

docs.aws.amazon.com

 

여기서 가장 힘들었던 부분은 UI호스팅 연결 부분이었다.

 

UI에서 로그인을 할 시 OAuth 토큰을 Code로 받을 예정이므로 Authorization code grant를 체크해줘야 한다.

 

 

 

 

로그인 및 로그아웃 URL이 있는데 UI호스팅에서 인증을 받은 후 불러올 URL이다. 로그인 페이지에서 구글 로그인을 인증하면 콜백 URL이 만들어지며, 코드를 받게 된다.  여기서 웹페이지를 닫고 인증된 Token Code를 갖고 어플리케이션에 돌아가야 한다.

 

웹페이지를 닫는 기능에 대해 밑의 링크를 참고하자.

https://docs.unity3d.com/Manual/enabling-deep-linking.html

 

Unity - Manual: Enabling deep linking

Using Unity as a Library in other applications Xcode frame debugger Unity integration Enabling deep linking Deep links are links that point directly to content within your application. Unity uses the Application.absoluteURL property and Application.deepLin

docs.unity3d.com

 

이렇게 인증된 코드는 

Userpool에 등록된 도메인 /? code= ----- = STATE로 다시 돌아오게 된다.

이 code를 토큰로 변형해 주어 저장하면 끝~

 

//인증코드를 토큰으로 바꿔준다.
    public async Task<bool> ExchangeAuthCodeForAccessToken(string rawUrlWithGrantCode)
    {
        Debug.LogError(rawUrlWithGrantCode);
        string allQueryParams = rawUrlWithGrantCode.Split('?')[1];

        // it's likely there won't be more than one param
        string[] paramsSplit = allQueryParams.Split('&');

        foreach (string param in paramsSplit)
        {
            // Debug.Log("param: " + param);

            // find the code parameter and its value
            if (param.StartsWith("code"))
            {
                string grantCode = param.Split('=')[1];
                string grantCodeCleaned = grantCode.removeAllNonAlphanumericCharsExceptDashes(); // sometimes the url has a # at the end of the string
                return await CallCodeExchangeEndpoint(grantCodeCleaned);
            }
            else
            {
                Debug.Log("Code not found");
            }
        }
        return false;
    }



    //바꾼 토큰을 임의 지점에 업데이트한다.
    private async Task<bool> CallCodeExchangeEndpoint(string grantCode)
    {
        WWWForm form = new WWWForm();
        form.AddField("grant_type", AuthCodeGrantType);
        form.AddField("client_id", AppClientID);
        form.AddField("code", grantCode);
        form.AddField("redirect_uri", RedirectUrl);

        // DOCS: https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html
        string requestPath = "https://" + AuthCognitoDomainPrefix + CognitoAuthUrl + TokenEndpointPath;

        UnityWebRequest webRequest = UnityWebRequest.Post(requestPath, form);
        await webRequest.SendWebRequest();

        if (webRequest.result != UnityWebRequest.Result.Success)
        {
            Debug.Log("Code exchange failed: " + webRequest.error + "\n" + webRequest.result + "\n" + webRequest.responseCode);
            webRequest.Dispose();
        }
        else
        {
            Debug.LogError("Success, Code exchange complete!");

            BADAuthenticationResultType authenticationResultType = JsonUtility.FromJson<BADAuthenticationResultType>(webRequest.downloadHandler.text);
            
            _userid = AuthUtilities.GetUserSubFromIdToken(authenticationResultType.id_token);

            // update session cache
            SaveDataManager.SaveJsonData(new UserSessionCache(authenticationResultType, _userid));
            webRequest.Dispose();
            
            return true;
        }
             return false;
    }