본문 바로가기

Daum Developers

서비스

Android 로그인 SDK 가이드

목차

소개

Android 앱 개발 시 Daum 아이디로 로그인 기능을 이용하여, 사용자 정보 확인 및 회원 인증으로 사용할 수 있습니다. 또한, Daum에서 제공하는 OAuth 2.0 기반으로 제공되는 인증형 API 기능을 부가적으로 활용할 수 있습니다.

요구 사항

  • 기본적인 Android 프로그래밍 능력
  • ClassPath에 아래 jar 파일 추가 - 다운로드 페이지
    • daum-oauth-android-1.0.2.jar

Client ID 발급

OAuth2를 이용하기 위해서는 Client ID가 필요합니다. 콘솔에서 App마다 Client ID를 발급 받으실 수 있습니다.아래 설명에서는 발급받은 client id를 123456789라고 가정하고 진행하겠습니다. 실제로 등록받으셔서 아래 내용을 따라가시길 바라고 예제로 사용하는 id는 정상동작하지 않습니다.

설치하기

안드로이드 OAuth 라이브러리를 적용하기 위해 가장 먼저 라이브러리를 설치해야 합니다. daum-oauth-android-1.0.2.jar 파일을 libs 디렉토리 밑으로 복사합니다. 자 이제 여러분은 OAuth 라이브러리 설치를 마쳤습니다.

간편 사용 가이드

OAuth2.0 스펙 및 URL 등을 모르셔도 사용가능합니다. OAuth2.0 을 지원하는 Daum의 인증형 Open API 만을 사용하여야 합니다. 아래 코드를 그대로 복사해서 사용하셔도 괜찮습니다.

AndroidManifest.xml 설정

intent-filter & android:launchMode 추가

<activity android:name="MainActivity"
      android:label="@string/app_name"
      android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
      android:launchMode="singleTask">

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

<intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="daum-17947856" />
</intent-filter>
</activity>
  • onNewIntent() 에서 Callback 처리를 위해 android:launchMode="singleTask" 옵셥을 추가합니다.
  • UrlScheme 을 받기 위해 intent-filter를 추가합니다.
    • scheme 은 daum-[발급받은 Client ID] 로 구성합니다.
    • daum-[발급받은 Client ID]-[custom suffix] 처럼 임의의 suffix를 붙여도 되지만 보통은 사용하지 않아도 괜찮습니다.

Permission추가

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

화면구성

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical" >

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:orientation="horizontal" >

    <Button
            android:id="@+id/verify"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="verifire" />

    <Button
            android:id="@+id/profile"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Profile" />

    <Button
            android:id="@+id/expire"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="expire" />
</LinearLayout>

<ScrollView
        android:id="@+id/sv_log"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >

    <TextView
            android:id="@+id/tv_log"
            style="@android:style/Widget.EditText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
</ScrollView>

</LinearLayout>

MainActivity class 만들기

client id 정의

static final String CLIENT_ID = "17947856"; // 테스트용

위 값은 예제를 위한 client id 값이므로 반드시 발급 받은 값을 사용해야 합니다.

onCreate()

TextView logText;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    MobileOAuthLibrary.getInstance().initialize(this, CLIENT_ID); // OAuth 라이브러리 초기화.

    logText = (TextView) findViewById(R.id.tv_log); // 로그를 보여줄 View

    Button verify = (Button) findViewById(R.id.verify);
    verify.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // access token 발급받기.
            MobileOAuthLibrary.getInstance().authorize(MainActivity.this, oAuthListener);
        }
    });

    Button profile = (Button) findViewById(R.id.profile);
    profile.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // oauth 2.0 을 지원하는 profile API 사용하기 
MobileOAuthLibrary.getInstance().requestResourceWithPath(getApplicationContext(),
oAuthListener, "/user/v1/show.json");
        }
    });

    Button expire = (Button) findViewById(R.id.expire);
    expire.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // access token 만료처리하기.
            MobileOAuthLibrary.getInstance().expireAuthorization();
            if (MobileOAuthLibrary.getInstance().isAuthorized()) {
                logText.append("expire fail");
            } else {
                logText.append("expire success");
            }
        }
    });

    // 인증 진행중 Activity가 내려간 경우를 위해 여기서도 처리해준다.
    Uri uri = getIntent().getData();
    if (uri != null) {
        // authorize() 호출 후에 url scheme을 통해 callback이 들어온다.
        MobileOAuthLibrary.getInstance().handleUrlScheme(uri);
    }
}

MobileOAuthLibrary.getInstance().requestResourceWithPath()는 OAuth 2.0을 지원하는 API가 아니면 정상동작하지 않으므로 사용시에 해당 API 가 OAuth 2.0 을 지원하는지 확인하여야 합니다.

onNewIntent()

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    Uri uri = intent.getData();
    if (uri != null) {
        // authorize() 호출 후에 url scheme을 통해 callback이 들어온다.
        MobileOAuthLibrary.getInstance().handleUrlScheme(uri);
    }
}

MobileOAuthLibrary.OAuthListener 추가

MobileOAuthLibrary.OAuthListener oAuthListener = new MobileOAuthLibrary.OAuthListener() {
    @Override
    public void onAuthorizeSuccess() {
        logText.append("onAuthorizeSuccess");
    }

    @Override
    public void onAuthorizeFail(OAuthError.OAuthErrorCodes errorCode, String errorMessage) {
        logText.append("onAuthorizeFail : " + errorMessage);
        if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorInvalidAuthorizationRequest)) {
        // 파라미터를 잘못 사용한 경우.
        } else if   (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorUnauthorizedClient)) {
        // 승인되지 않은 Client ID 를 사용한 경우         } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorAccessDenied)) {
        // 사용자가 승인 페이지에서 "취소"를 누른 경우         } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorUnsupportedResponseType)) {
        // 지원되지 않는 인증방식을 사용한 경우         } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorInvalidScope)) {
        // 유효한 권한 요청이 아닌 경우.
        }
    }

    @Override
    public void onRequestResourceSuccess(String response) {
        // 결과 피싱은 앱에서 담당한다.
        logText.append("onRequestResourceSuccess : " + response);
    }

    @Override
    public void onRequestResourceFail(OAuthError.OAuthErrorCodes errorCode, String errorMessage) {
        logText.append("onRequestResourceFail : " + errorMessage);
        if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorInvalidToken)) {
            // access token 이 없거나 만료처리된 경우 or 401 에러             // authorize() 를 통해 다시 access token을 발급 받아야함.
        } else if   (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorInvalidResourceRequest)) {
            // 서버와 통신중 400 에러가 발생한 경우         } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorInsufficientScope)) {
            // 서버와 통신중 403 에러가 발생한 경우         } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorServiceNotFound)) {
            // 서버와 통신중 404 에러가 발생한 경우         } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorNetwork)) {
            // 현재 휴대폰의 네트워크를 이용할 수 없는 경우         } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorServer)) {
            // 서버쪽에서 에러가 발생하는 경우             // 서버 페이지에 문제가 있는 경우이므로 api 담당자와 얘기해야함.
        } else if (errorCode.equals(OAuthError.OAuthErrorCodes.OAuthErrorUnknown)) {
            // 서버와 통신중 그 외 알수 없는 에러가 발생한 경우.
        }
    }
};

OAuthError.OAuthErrorCodes enum class로 만들어져 있으며 발생할 수 있는 모든 에러에 대한 내용은 위 샘플코드 이외에는 없으므로 원하는 적절한 처리를 해주면 됩니다.

onDestroy()

@Override
protected void onDestroy() {
    super.onDestroy();
    // 사용이 끝나면 반드시 호출해주어야 한다.
    MobileOAuthLibrary.getInstance().uninitialize();
}

인증형 API 사용하기

인증형 API는 유효한 access token이 있을 때만 사용이 가능합니다. 사용자 프로필 API를 예로 들면 아래와 같이 사용할 수 있습니다.

MobileOAuthLibrary.getInstance().requestResourceWithPath(getApplicationContext(), oAuthListener, "/user/v1/show.json");

이용사례

좋은 사례를 갤러리에 올려주시면, 검토 후 추가하겠습니다.

참조링크