Develop/Java

[AWS] 아마존 웹 서비스 Android + Amazon Cognito 구현

JunJangE 2021. 7. 14. 11:28

지난번에 AWS Amplify와 Android 앱을 연동해보았다.

 

[AWS] 아마존 웹 서비스 Amplify + Android 프로젝트 연동

Android 앱과 AWS의 서비스를 연동해보자. 클라우드 서비스 | 클라우드 컴퓨팅 솔루션| Amazon Web Services 제조 AWS를 활용한 Siemens의 에너지, 의료 서비스, 제조 분야 혁신 Siemens가 AWS를 사용하여 어떻게

fre2-dom.tistory.com

이번에는 연동된 안드로이드 앱을 Amazon Cognito를 활용하여 소셜 로그인 연동을 해보도록 하겠다.

Amazon Cognito를 사용하면 웹과 모바일 앱에 빠르고 손쉽게 사용자 가입, 로그인 및 액세스 제어 기능을 추가할 수 있다. Amazon Cognito에서는 수백만의 사용자로 확장할 수 있고, Apple, Facebook, Google 및 Amazon과 같은 소셜 자격 증명 공급자와 엔터프라이즈 자격 증명 공급자(SAML 2.0 및 OpenID Connect 사용)를 통한 로그인을 지원한다.

우선 다음 사항을 체크해본다.

  • Amplify 라이브러리가 통합된 Android SDK API 레벨 16 이상을 대상으로 하는 Android 애플리케이션

그럼 이제 본격적으로 Amazon Cognito 구현을 해보자.

처음에 Auth를 생성한다.

cmd 창을 열고, cd 커맨드로 연동할 안드로이드 프로젝트 폴더를 이동해준다.

amplify add auth

그리고 위 코드를 입력해준다.

그럼 위 사진과 같이 뜨게 되는데 각 유형에 대해서 확인해보자.

  • Default configuration : 기본 설정으로 userpool 생성 및 보안 설정을 해준다.
  • Default configuration with Social Provider (Federation) : 기본 설정과 함께 소셜 인증 방식의 userpool 생성 및 보안 설정을 이용할 때 사용한다.
  • Manual configuration : 사용자가 userpool 생성 및 보안 설정 방식을 직접 입력해서 사용한다.

일단 기본 설정으로 선택해주었다. 그 후 인증 방식 종류가 나오는데 Email 을 선택하고 이후 추가 설정할 필요는 없기 때문에 'No, I am done'으로 선택하면 생성이 된다.

다음으로는 아래 코드를 입력하여 프로젝트를 갱신해준다.

amplify push

대략 4분 정도? 지나면 갱신이 된다

확인하고 싶으면 AWS management console에서 [해당 Amplify 앱] - [Backend environments] - [dev]로 들어가 push 내역을 보면 된다.

이제 안드로이드 프로젝트를 수정해야 한다.

Gradle Scripts -> build.gradle(Module: amplify_test.app)을 누른다.

build.gradle(Module: amplify_test.app)에 들어가게 되면 밑에 부분에 위 사진처럼 dependencies { }을 볼 수 있다.

dependencies { } 안에 다음 코드를 입력한다.

// SDK 초기화를 위한 모바일 클라이언트
implementation('com.amazonaws:aws-android-sdk-mobile-client:2.8.+@aar') { transitive = true }

// 로그인을 위한 Cognito UserPools
implementation('com.amazonaws:aws-android-sdk-auth-userpools:2.8.+@aar') { transitive = true }

// 로그인 UI 라이브러리
implementation('com.amazonaws:aws-android-sdk-auth-ui:2.8.+@aar') { transitive = true }

코드를 작성하면 오른쪽 상단에  Sync now 라는 버튼이 나타나고 클릭하여 Sync 해준다.

다음은 인증을 위한 화면을 구현하기 위해 새로운 액티비티를 만들어준다.

New -> Activity -> Empty Activity 클릭하여 Activity 이름을 설정하여 생성해준다.

여기서는 AuthActivity로 이름으로 설정하고 'Finish' 버튼을 눌러 액티비티를 하나 만들어준다. 그리고 다음 코드를 AuthActivity에 입력한다.

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.amazonaws.mobile.client.AWSMobileClient;
import com.amazonaws.mobile.client.Callback;
import com.amazonaws.mobile.client.SignInUIOptions;
import com.amazonaws.mobile.client.UserStateDetails;

public class AuthActivity extends AppCompatActivity {

    private final String TAG = AuthActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auth);

        AWSMobileClient.getInstance().initialize(getApplicationContext(), new Callback<UserStateDetails>() {

            @Override
            public void onResult(UserStateDetails userStateDetails) {
                Log.i(TAG, userStateDetails.getUserState().toString());
                
                // userStateDetails을 통해 사용자 인증에 대한 상태 정보에 따라 로그인 
                switch (userStateDetails.getUserState()){
                    case SIGNED_IN:
                        Intent i = new Intent(AuthActivity.this, MainActivity.class);
                        startActivity(i);
                        break;
                    case SIGNED_OUT:
                        showSignIn();
                        break;
                    default:
                        AWSMobileClient.getInstance().signOut();
                        showSignIn();
                        break;
                }
            }

            @Override
            public void onError(Exception e) {
                Log.e(TAG, e.toString());
            }
        });
    }

    private void showSignIn() {
        try {
            AWSMobileClient.getInstance().showSignIn(this,
                    SignInUIOptions.builder().nextActivity(MainActivity.class).build());
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

}

이제 mainfests -> AndroidMainfest.xml에 들어가 처음에 인증 화면을 나오게 설정한다.

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Amplify_test">

        <activity android:name=".MainActivity">
        </activity>

        <activity android:name=".AuthActivity"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

바뀐 코드는 처음에 나오게 하는 액티비티를 AuthActivity로 바꾸었고 noHistory를 true로 하여 화면 스택이 쌓이지 않고 바로 넘어가도록 구현하였다.

위 코드로 모두 작성하고 실행하면 원래는 다음 사진과 같이 나와야 한다.

하지만 다음과 같은 에러가 나오면서 실행이 안될 수 있다.

E/AndroidRuntime: FATAL EXCEPTION: Thread-2 Process: com.junjange.amplify_test, PID: 24726 java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/app/AppCompatActivity;

며칠 동안 구글링 하고 유튜브로 검색한 결과..

로그인 UI나 showSignIn 관련해서 문제가 있는 거 같은데.. 버전 호환이 안되거나 aws 로그인 부분이 이상한 거 같다는 판단이 나왔다.

혹시 해결 방법을 아시는 분은 댓글이나 연락 주시면 감사할 거 같다.

참고

 

Authentication - Getting started - Amplify Docs

The Amplify Framework uses Amazon Cognito as the main authentication provider. Learn how to handle user registration, authentication, account recovery & other operations.

docs.amplify.aws