'네이버로그인'에 해당되는 글 1건

  1. 2017.10.30 안드로이드 네이버 아이디로 로그인 API 적용.
안드로이드2017. 10. 30. 03:34

네이버 개발자 센터의 레퍼런스 코드를 기준으로 작성되었다.

https://developers.naver.com/docs/login/android/


필요한 환경 설정은 위 사이트를 참고하여 세팅하면 된다.


내 경우 외부 클래스를 별도로 만들어 로그인을 처리했다. 로그인 버튼은 커스텀 이미지를 사용했다.


public class NaverLogin {
  private OAuthLogin mOAuthLoginInstance;
  private Context mContext;

  public NaverLogin(Context mContext) {
    this.mContext = mContext;
    initNaverAuthInstance();
  }

  // API 인스턴스를 초기화
  private void initNaverAuthInstance() {
    final Striing OAUTH_CLIENT_ID = "7o6Aqvtqr11ap1MdnH58";
    final String OAUTH_CLIENT_SECRET = "2IbCBMfSLt";
    final String OAUTH_CLIENT_NAME = "네이버 아이디로 로그인";
    mOAuthLoginInstance = OAuthLogin.getInstance();
    mOAuthLoginInstance.init(mContext, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_CLIENT_NAME);
  }
  
  // 로그인 처리
  public void forceLogin() {
    mOAuthLoginInstance.startOauthLoginActivity((Activity)mContext, mOAuthLoginHandler);
  }

  // 로그아웃 처리(토큰도 함께 삭제)
  public forceLogout() {
    // 스레드로 돌려야 한다. 안 그러면 로그아웃 처리가 안되고 false를 반환한다.
    new Thread(new Runnable() {
      @Override
      public void run() {
        mOAuthLoginInstance.logoutAndDeleteToken(mContext);
      }
    }).start();
  }

  // 로그인을 처리할 핸들러
  private OAuthLoginHandler mOAuthLoginHandler = new OAuthLoginHandler() {
    @Override
    public void run(boolean success) {
      if(success) {
        String accessToken = mOAuthLoginInstance.getAccessToken(mContext);
        String refreshToken = mOAuthLoginInstance.getRefreshToken(mContext);
        String tokenType = mOAuthLoginInstance.getTokenType(mContext);
        long expiresAt = mOAuthLoginInstance.getExpiresAt(mContext);
        
        new RequestApiTask(accessToken).execute(); // 로그인이 성공하면 네이버의 계정 정보를 가져온다.
      } else {
        // 로그인 실패 처리
      }
    }
  };

이어서 로그인 성공 시 해당 계정 정보를 가져오는 작업을 한다.

  private class RequestApiTask extends AsyncTask {
    private String token;

    RequestApiTask(String token) {
      this.token = token;
    }

    @Override
    protected void onPostExecute(StringBuffer result) {
      super.onPostExecute(result);
      // 로그인 처리가 완료되면 수행할 로직 작성
      processAuthResult(result);
    }

    @Override
    protected StringBuffer doInBackground(Void... params) {
      String header = "Bearer " + token;
      try {
        final String apiURL = "https://openapi.naver.com/v1/nid/me";
        URL url = new URL(apiURL);
        HttpURLConnection con = (HttpURLConnection)url.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("Authorization", header);
        int responseCode = con.getResponseCode();

        BufferedReader br = new BufferedReader(new InputStreamReader(
                                      responseCode == 200 ? con.getInputStream() : con.getErrorStream()));

        String inputLine;
        StringBuffer response = new StringBuffer();
        while((inputLine = br.readLine()) != null) {
          response.append(inputLine);
        }

        br.close();
        return response;

      } catch(Exception e) {
        e.printStackTrace();
      }

      return null;
    }
  }

로그인의 계정 정보를 가져와서 처리하는 작업을 한다.

9월부터 계정 정보 요구 시 개인 정보 제공을 거부할 수 있기 때문에 이것에 대한 처리가 필요했다.


계정 정보는 JSON 형식으로 반환되는데, 이를 디코드해주면 다음과 같은 데이터를 조회할 수 있다.

{"resultcode":"00","message":"success",
    "response":{
        "nickname":"...","enc_id":"...","profile_image":"...","age":"...",
        "gender":"...","id":"...","name":"...","email":"...","birthday":"..."
    }
}

필요한 정보는 response라는 객체 안에 들어있기 때문에 최초 반환된 JSON 데이터에서는 정보를 가져올 수 없다.

  private void processAuthResult(StringBuffer response) {
    try {
      // response는 json encoded된 상태이기 때문에 json 형식으로 decode 해줘야 한다.
      JSONObject object = new JSONObject(response.toString());
      JSONObject innerJson = new JSONObject(object.get("response").toString());

      // 만약 이메일이 필요한데 사용자가 이메일 제공을 거부하면 
      // JSON 데이터에는 email이라는 키가 없고, 이걸로 제공 여부를 판단한다.
      if(!innerJson.has("email")) {        
        final Dialog dialog = Util.getOneDialog(mContext); // Util.getOneDialog 구현은 생략.
        TextView content = (TextView)dialog.findViewById(R.id.one_dialog_content);
        content.setText("이메일 정보 제공에 동의해주세요.");
        Button dialogBtn = (Button)dialog.findViewById(R.id.one_dialog_btn_ok);
        dialogBtn.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            dialog.dismiss();
            forceLogout();
          }
        });
      } else {        
        String account = innerJson.getString("email");
        String nickname = innerJson.getString("nickname");
        String profileImgUrl = innerJson.getString("profile_image");
        // 원하는 모든 과정이 처리가 되면 해당 멤버 데이터를 가지고 다음 로직을 수행한다.
        // checkMember(account, nickname, profileImgUrl.replaceAll("\\\\", ""));
      }
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
}

필요한 정보 제공을 거부할 경우 네이버 로그인이 정상적으로 처리되어도 강제로 로그아웃 시키고 토큰도 삭제한다.

그리고 다시 로그인 화면으로 보내서 로그인을 요청.

Posted by 홍규홍규