🤗 Android SMS 본인인증 구현하기
Android에서 SMS 본인인증을 구현하는 방법에는 여러가지 방법이 있습니다.
1) 서버에서 문자 인증 체계를 구축하여 진행하는 방법
2) PG사에서 제공하는 본인 인증 API를 이용하여 구축하는 방법
등..
이 글에서는 2번, 그 중 아래와 같은 화면에서 인증을 하는 방법을 구현해보도록 하겠습니다.
위는 다날(Danal) PG사에서 제공하는 API를 이용한 인증시스템의 한 화면인데요,
이를 쉽고 간편하게 구현하기 위한 API를 아임포트에서 제공합니다.
따라서 이 글에서는 아임포트 플랫폼을 이용하여 진행하도록 하겠습니다.
제가 작성한 Full 예제는 여기서 확인하실 수 있습니다.
https://github.com/zladnrms/IamportAuthExample
📕 시작하기 전에..
아임포트 공식 개발가이드에서 나와있듯이, 웹뷰를 통한 인증 후 결과를
Android Code (Java Or Kotlin)으로 얻어와서 처리하는 방법을취해야 합니다.
그러니까 본인인증을 위한 처리 순서를 대분류로 나눠보자면,
안드로이드에서 본인인증 시도 -> 웹뷰를 통한 본인인증 -> 결과를 안드로이드로 가져옴 -> 처리
의 순서를 취하게 됩니다.
글 작성은, 첫번째로는 아임포트 가이드라인을 충실히 따른 순서로 작성할 것이며,
그 하단에는 제가 실무에 적용한 방법을 그대로 기술하겠습니다.
📗 개발 방법
1. 인증 웹뷰로 사용할 html 파일을 작성해줍니다. 이 예시는 아임포트 공식 홈페이지에서 소개중입니다.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" ></script>
<script type="text/javascript" src="https://cdn.iamport.kr/js/iamport.payment-1.1.5.js" ></script>
</head>
<body>
<!-- 아임포트 자바스크립트는 jQuery 기반으로 개발되었습니다 -->
<script type="text/javascript">
var IMP = window.IMP; // 생략가능
IMP.init('iamport'); // 'iamport' 대신 부여받은 "가맹점 식별코드"를 사용
/* 중략 */
IMP.certification({
merchant_uid : 'merchant_' + new Date().getTime() //본인인증과 연관된 가맹점 내부 주문번호가 있다면 넘겨주세요
}, function(rsp) {
if ( rsp.success ) {
// 인증성공
console.log(rsp.imp_uid);
console.log(rsp.merchant_uid);
$.ajax({
type : 'POST',
url : '/certifications/confirm',
dataType : 'json',
data : {
imp_uid : rsp.imp_uid
}
}).done(function(){
takeResponseAndHandle(rsp)
});
} else {
// 인증취소 또는 인증실패
var msg = '인증에 실패하였습니다.';
msg += '에러내용 : ' + rsp.error_msg;
alert(msg);
}
});
function takeResponseAndHandle(rsp) {
if ( rsp.success ) {
// 인증성공
console.log(rsp.imp_uid);
console.log(rsp.merchant_uid);
} else {
// 인증취소 또는 인증실패
var msg = '인증에 실패하였습니다.';
msg += '에러내용 : ' + rsp.error_msg;
alert(msg);
}
}
</script>
</body>
</html>
Hot Ez Ex)
가맹점 식별코드 : 아임포트 관리자 페이지의 '내 정보'에 있는 imp로 시작하는 문자열을 넣어줍니다.
여기까지만 진행하셨어도 html를 브라우저로 실행시켜보시면 아래와 같은 인증 페이지가 뜨게 될 것 입니다.
그렇다면 웹뷰의 자바스크립트쪽 소스를 간략하게 알아봅시다.
<script>
IMP.certification({
merchant_uid : 'merchant_' + new Date().getTime() //본인인증과 연관된 가맹점 내부 주문번호가 있다면 넘겨주세요
}, function(rsp) {
if ( rsp.success ) { //(1) 인증에 성공 시!!
console.log(rsp.imp_uid);
console.log(rsp.merchant_uid);
$.ajax({
type : 'POST',
url : '/certifications/confirm',
dataType : 'json',
data : {
imp_uid : rsp.imp_uid
}
}).done(function(){
takeResponseAndHandle(rsp)
});
} else { //(2) 인증 취소 또는 인증 실패 시
var msg = '인증에 실패하였습니다.';
msg += '에러내용 : ' + rsp.error_msg;
alert(msg);
}
});
</script>
본인 인증이 성공해야만 rsp 내의 변수를 처리할 수 있으며, 아닐 시 else 블록 내의 처리로 넘어가게 되는 것 인데요, 그중에
$.ajax({
}).done(function(){
});
이 처리의 경우, 본인인증이 성공하였을 때, 자신의 서버에서 처리를 해줄 것이 있다면 해주는 것이고, 아니라면 필요없는 부분입니다.
이와는 별개로, 본인인증에 성공한 사람의 정보 (성별, 이름 등)을 확인하고싶다면, iamport의 rest api를 이용하여 받아와야 합니다.
이는, 여기에서 쉽게 찾아 볼 수 있습니다.
📘 WebView는 완성, 연결은?
인증에 성공했거나 실패하였을 때, 해당 여부를 안드로이드와 통신하여야 합니다.
이것은 안드로이드와 자바스크립트의 연동을 통하여 처리하게 됩니다.
우선, 안드로이드에서 해당 처리를 위한 Class를 만들어줍니다.
import android.webkit.JavascriptInterface
class SmsAuthFactory(activity: Activity) {
private val TAG = "SmsAuthFactory★"
@JavascriptInterface
fun resultAuth(message: String) {
//javascript로 부터 온 parameter (message)를 처리
}
}
resultAuth 함수가 있고, JavascriptInterface Annotation이 붙어있습니다.
자바스크립트와 연동되는 인터페이스를 이용하는 함수인가? 라는 생각을 할 수 있습니다.
하지만 여기까지만 보면 이해가 잘 되지 않습니다.
그러므로 이어서 자바스크립트에서 안드로이드로 값을 보내는 역할을 하는 처리를 보도록 합시다.
<script>
...중략...
window.AndroidBridge.resultAuth('success');
</script>
window객체 뒤의 AndroidBridge는 조만간 따로 만들어줄 namespace 같은 값입니다.
근데 resultAuth('success'); 부분을 잘 보면, 위에 JavascriptInterface Annotation을 붙인 함수와 이름이 같다는 것을 알 수 있습니다.
즉 window.AndroidBridge를 통하여 위에 만든 SmsAuthFactory의 resultAuth 함수로 값을 전달할 수 있다는 것이겠지요?
이러한 방식으로 안드로이드와 자바스크립는 상호작용하게 됩니다.
이제 마지막으로, 본인인증 웹뷰를 띄우는 안드로이드 Activity에서의 처리를 봅시다.
웹뷰와 위의 SmsAuthFactory를 연결하는 한 줄의 코드면 해결됩니다.
webView.addJavascriptInterface(SmsAuthFactory(), "AndroidBridge")
SmsAuthFactory 클래스를 AndroidBridge라는 namespace로 javascript window 객체에 만들어주는 것입니다.
그러면 자바스크립트쪽 소스 코드를 정리해보겠습니다.
<script>
IMP.certification({
merchant_uid : 'merchant_' + new Date().getTime() //본인인증과 연관된 가맹점 내부 주문번호가 있다면 넘겨주세요
}, function(rsp) {
if ( rsp.success ) { //(1) 인증에 성공 시!!
console.log(rsp.imp_uid);
console.log(rsp.merchant_uid);
$.ajax({
type : 'POST',
url : '/certifications/confirm',
dataType : 'json',
data : {
imp_uid : rsp.imp_uid
}
}).done(function(){
takeResponseAndHandle(rsp)
});
} else { //(2) 인증 취소 또는 인증 실패 시
var msg = '인증에 실패하였습니다.';
msg += '에러내용 : ' + rsp.error_msg;
alert(msg);
}
});
</script>
인증의 결과 여부를 AndroidBridge라 명명한 SmsAuthFactory 클래스를 통하여 안드로이드로 전달하는 코드입니다.
📚 감 잡기 끝.. 합치자!
여기까지는 감잡기 및 전체적인 틀을 알고 자유자재로 처리하기 위한 밑받침이었습니다.
아래부터는 실전에서 본인인증 후, 인증 성공 시 해당 인증정보까지 받아오는 처리를 해보도록 하겠습니다.
📙 구성요소
본인 인증 화면으로 넘어가기 위한 버튼 존재 액티비티
본인 인증을 진행하는 WebView Activity
자바스크립트와 안드로이드의 Interface 역할을 하는 SmsAuthFactory Class
WebView를 구성하는 html
이렇게 총 4가지가 필요합니다.
본인 인증 화면으로 넘어가기 위해서, 버튼 클릭 이벤트가 발생했을 때
본인인증 WebView Activity를 startActivityForResult를 통하여 실행시키도록 합니다.
startActivityForResult(..., SMS_AUTH_REQ_CODE)
그리고 위의 SmsAuthFactory Class에서 조금 추가해줄 사항이 있습니다.
import android.app.Activity
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.webkit.JavascriptInterface
class SmsAuthFactory(activity: Activity) {
private val TAG = "SmsAuthFactory★"
private val activity = activity
@JavascriptInterface
fun resultAuth(message: String, impKey: String?) {
val intent = Intent()
if(message == "success" && impKey != null) {
intent.putExtra("result","success")
intent.putExtra("imp_key", impKey)
activity.setResult(RESULT_OK,intent)
activity.finish()
}
else {
intent.putExtra("result","failure")
activity.setResult(RESULT_OK,intent)
activity.finish()
}
}
}
Hot Ez Ex) getString(R.string.imp_key)와 getString(R.string.imp_secret)은 i'amport 관리자 페이지의 가맹점 식별코드 아래에 있는 2가지를 의미하며, impKey는 인증에 성공했을 시 받을 수 있는 자바스크립트 상에서의 imp_key를 의미한다.
이제 자바스크립트를 아주 조금 손보면 됩니다.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == SMS_AUTH_REQ_CODE) {
data?.let {
it.getStringExtra("result")?.let { result ->
Toast.makeText(this, result, Toast.LENGTH_SHORT).show()
}
it.getStringExtra("imp_key")?.let { impKey ->
viewModel.smsAuthPostAccessToken(getString(R.string.imp_key), getString(R.string.imp_secret), impKey)
} ?: Toast.makeText(this, "인증 결과가 누락되었습니다.\n재인증이 필요합니다.", Toast.LENGTH_SHORT).show()
}
}
}
위에서 변수 한 개를 넘기는 것이 추가되었습니다. (rsp.imp_uid)
이를 넘김으로써 해당 유저의 정보(이름, 핸드폰 번호 등)을 추적할 수 있습니다.
이제 이 정도면 인증 과정은 모두 끝났습니다.
다음은 아임포트에서 제공하는 rest api를 통하여 해당 유저의 정보를 받아오는 처리를 진행하도록 하겠습니다
https://zladnrms.tistory.com/61?category=861489
#안드로이드 iamport 연동 #안드로이드 문자인증
'Android > 연동 방법' 카테고리의 다른 글
[Android/연동방법] SMS 본인인증 연동 (with iamport, 아임포트) (2) (3) | 2019.10.14 |
---|---|
[Android/연동 방법] Google Play Console 프로덕션 Key Hash 얻기 (0) | 2019.09.16 |
[안드로이드/Android] Android Studio BitBucket 연동 방법 (0) | 2019.08.22 |
[안드로이드/Android] Android Studio 통해 SHA1 Key 매우 쉽게 알아내기 (0) | 2019.08.20 |