네이버 개발자 센터의 레퍼런스 코드를 기준으로 작성되었다.
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();
}
}
}
필요한 정보 제공을 거부할 경우 네이버 로그인이 정상적으로 처리되어도 강제로 로그아웃 시키고 토큰도 삭제한다.
그리고 다시 로그인 화면으로 보내서 로그인을 요청.
'안드로이드' 카테고리의 다른 글
Push rejected: Push to origin/master was rejected (0) | 2018.05.01 |
---|---|
이클립스 로그캣 텍스트 색깔 변경 (0) | 2018.04.29 |
java exception was raised during method invocation 오류 (0) | 2017.12.22 |
이클립스에서 안드로이드 7.0 이상 기기가 target unknown 뜨는 현상 (2) | 2017.12.05 |
Unable to build: the file dx.jar was not loaded from the SDK folder! 오류 해결 (4) | 2017.11.07 |