안드로이드 휴대폰 인증 소스 | 이게 켜져 있으면 내 정보 밤새 다 빠져나갑니다!! 휴대폰 설정 4가지 무조건 꺼 놓으세요! 30 개의 베스트 답변

당신은 주제를 찾고 있습니까 “안드로이드 휴대폰 인증 소스 – 이게 켜져 있으면 내 정보 밤새 다 빠져나갑니다!! 휴대폰 설정 4가지 무조건 꺼 놓으세요!“? 다음 카테고리의 웹사이트 you.maxfit.vn 에서 귀하의 모든 질문에 답변해 드립니다: https://you.maxfit.vn/blog. 바로 아래에서 답을 찾을 수 있습니다. 작성자 버미쌤 이(가) 작성한 기사에는 조회수 8,343,382회 및 좋아요 118,084개 개의 좋아요가 있습니다.

안드로이드 휴대폰 인증 소스 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 이게 켜져 있으면 내 정보 밤새 다 빠져나갑니다!! 휴대폰 설정 4가지 무조건 꺼 놓으세요! – 안드로이드 휴대폰 인증 소스 주제에 대한 세부정보를 참조하세요

저한테 엊그제 국제전화 한통이 걸려왔는데요. 뭔가 싶어서 전화를 받았는데. 웬 중국인이 저한테 뭐라고 뭐라고 하는 전화를 받았어요. 좀 이상하다 싶어서 검색해봤는데, 저만 전화를 받은 게 아니더라고요. 지금 현재 중국에서 전화가 오는 사례가 늘어나고 있데요. 그래서 많은 분들이 추측하기를 최근 페이스북에서 개인정보가 유출된 영향일 수 있다고 지금 이야기하고 있는데요. 아.. 진짜 무서운 세상입니다. 문자사기다 보이스피싱이다. 이제는 대기업까지 개인정보가 유출되고 있고 있습니다. 이런 상황에서 내 개인정보는 내가 잘 지켜야하겠죠. 그래서 준비해봤고요. 내 핸드폰 개인정보를 지킬 수 있는 방법 4가지를 준비해봤습니다. 어렵지 않으니까 꼭! 따라하셔서 설정해두면 좋을 것 같아요. #개인정보유출, #해킹, #개인정보, #휴대폰설정,
Song : Masteck Media – Light Corporate
https://soundcloud.com/masteck_media
Music Promoted by DayDreamSound https://youtu.be/JjxStRnRHo0

안드로이드 휴대폰 인증 소스 주제에 대한 자세한 내용은 여기를 참조하세요.

[Android/연동방법] SMS 본인인증 연동 (with iamport, 아임포트 …

그렇다면 웹뷰의 자바스크립트쪽 소스를 간략하게 알아봅시다.

Hot Ez Ex)

가맹점 식별코드 : 아임포트 관리자 페이지의 '내 정보'에 있는 imp로 시작하는 문자열을 넣어줍니다.

아임포트 관리자페이지의 '내 정보'

여기까지만 진행하셨어도 html를 브라우저로 실행시켜보시면 아래와 같은 인증 페이지가 뜨게 될 것 입니다.

실행 결과

그렇다면 웹뷰의 자바스크립트쪽 소스를 간략하게 알아봅시다.

본인 인증이 성공해야만 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이 붙어있습니다.

자바스크립트와 연동되는 인터페이스를 이용하는 함수인가? 라는 생각을 할 수 있습니다.

하지만 여기까지만 보면 이해가 잘 되지 않습니다.

그러므로 이어서 자바스크립트에서 안드로이드로 값을 보내는 역할을 하는 처리를 보도록 합시다.

window객체 뒤의 AndroidBridge는 조만간 따로 만들어줄 namespace 같은 값입니다.

근데 resultAuth('success'); 부분을 잘 보면, 위에 JavascriptInterface Annotation을 붙인 함수와 이름이 같다는 것을 알 수 있습니다.

즉 window.AndroidBridge를 통하여 위에 만든 SmsAuthFactory의 resultAuth 함수로 값을 전달할 수 있다는 것이겠지요?

이러한 방식으로 안드로이드와 자바스크립는 상호작용하게 됩니다.

이제 마지막으로, 본인인증 웹뷰를 띄우는 안드로이드 Activity에서의 처리를 봅시다.

웹뷰와 위의 SmsAuthFactory를 연결하는 한 줄의 코드면 해결됩니다.

webView.addJavascriptInterface(SmsAuthFactory(), "AndroidBridge")

SmsAuthFactory 클래스를 AndroidBridge라는 namespace로 javascript window 객체에 만들어주는 것입니다.

그러면 자바스크립트쪽 소스 코드를 정리해보겠습니다.

인증의 결과 여부를 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를 의미한다.

바로 이 2가지!

이제 자바스크립트를 아주 조금 손보면 됩니다.

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, "인증 결과가 누락되었습니다.

재인증이 필요합니다.", Toast.LENGTH_SHORT).show() } } }

위에서 변수 한 개를 넘기는 것이 추가되었습니다. (rsp.imp_uid)

이를 넘김으로써 해당 유저의 정보(이름, 핸드폰 번호 등)을 추적할 수 있습니다.

이제 이 정도면 인증 과정은 모두 끝났습니다.

다음은 아임포트에서 제공하는 rest api를 통하여 해당 유저의 정보를 받아오는 처리를 진행하도록 하겠습니다

https://zladnrms.tistory.com/61?category=861489

#안드로이드 iamport 연동 #안드로이드 문자인증

[Java][Android] SMS 인증 기능 만들기

안녕하세요.

오늘은 저번 시간에 작성한 "SMS 발송 기능"에 인증번호를 보내서 인증하는 기능을 만들어 보겠습니다.

- 스틱코드?

stickode.com/mainlogin.html

- SMS 발송 기능

https://stickode.tistory.com/44

1. 레이아웃

인증번호를 확인 할 인풋창과 버튼 생성

▶ 인증번호를 확인하는 인풋창과 버튼을 만들어줍니다.

▶ 아래는 레이아웃에 대한 전체 코드입니다.

- activity_main.xml

휴대폰 인증 로직 구현하기

이번 로그에서는 허위유저의 가입을 방지하기 위해 회원가입을 위한 절차 중 SMS를 이용한 휴대폰 인증 기능을 구현한 것에 대해 다뤄보고자 한다.

휴대폰 인증 개요

부동산 앱의 특성상 개인정보가 확인된 실 사용유저 중심으로 회원가입 절차를 구축하는 작업이 필요하였다. 이를 위해 보편적으로 사용되고 있는 SMS를 이용한 휴대폰 본인인증 확인 과정을 구현하도록 하였다.

이를 위해 고려된 사항으로는 다음과 같다.

유저에게 랜덤한 4자리의 인증번호를 전송하고, 유저가 다시 응답한 인증번호와 유저에게 보낸 인증번호를 비교한다. 인증번호가 확인되면 유저 편의를 위하여 해당 휴대폰 번호를 다음 절차에서 다시 입력할 필요 없도록 한다.

회원가입 및 휴대폰 인증 아키텍쳐

이를 위해 휴대폰 인증 과정을 거치는 회원가입 로직은 아래와 같다.

회원정보를 입력하기 전에 signUp 버튼을 눌러 핸드폰 인증화면으로 이동하도록 한다. 서버로 인증 번호를 요청하면 해당 api에서 인증번호를 생성하여 twilio Programmable SMS api 통해 유저에게 인증번호를 전송한다. 인증번호를 확인한 유저는 번호를 화면에 입력하게 되고, 다시 한번 검증과정을 담당하는 서버 api로 요청을 보내게 된다. 서버에서 최종적으로 인증번호를 확인하면 정상적으로 요청받은 경우 회원정보를 입력하는 스크린으로 이동하게 된다. 인증번호가 잘못된 경우는 상황에 따른 에러핸들링을 통해 유저에게 alert로 알려준다.

소스코드

./src/controllers/auth.ts

const { userPhoneNum } = req . body ; try { tempAuthObj = await twilioHelper . auth ( userPhoneNum ) ; if ( tempAuthObj instanceof Error ) { res . status ( 500 ) . json ( { error : tempAuthObj . message } ) ; } else { res . sendStatus ( 200 ) ; } } catch ( err ) { console . error ( 'error is ' , err ) ; res . status ( 500 ) . json ( { error : err } ) ; }

./src/controllers/auth.ts

const { userVerifyNum , userPhoneNum } = req . body ; if ( userVerifyNum !== undefined && userPhoneNum !== undefined ) { if ( tempAuthObj [ userPhoneNum ] === Number ( userVerifyNum ) ) { delete tempAuthObj [ userPhoneNum ] ; res . sendStatus ( 200 ) ; } else { res . sendStatus ( 401 ) ; } } else { if ( userPhoneNum === undefined || userPhoneNum === '' ) { res . status ( 400 ) . json ( '변경할 휴대폰 번호를 입력해주세요' ) ; } else if ( userVerifyNum === undefined ) { res . status ( 400 ) . json ( '인증번호를 입력해주세요' ) ; } else { res . status ( 400 ) . json ( '변경할 휴대폰 번호를 입력해주세요' ) ; } }

구동 테스트

결론

처음에는 nodemailer와 같은 메일을 이용해서 인증번호를 보내는 방식을 고려하였다. 하지만 스마트폰 앱으로 구동되는 서비스인 만큼 sms로 인증과정을 처리하는 방식이 훨씬 유저 편의적인 관점에서 좋을 것 판단에 따라 twilio programmble sms api를 사용하기로 하였고, 지금 와서 생각해 보면 좋은 선택이었다고 생각한다.

하지만 휴대폰 인증 로직을 구현하면서 보완해야할 부분이라고 느꼈던 점이 있는데, 먼저 sms api를 처리하는데 있어 정보가 유출되지 않도록 보안에 조금 더 신경써야 하겠다는 점이었다. twilio 공식문서를 확인하면 programmable sms api 외에 verify api를 별도로 지원하고 있다. 따라서 단순히 sms를 보내서 인증번호를 확인하는 작업보다 verify api에서 지원하는 메소드를 이용하여 인증과정을 거치는 방식이 훨씬 보안적인 측면에서 우수할 것이라고 생각된다.

참고자료

안드로이드 본인인증하기 (다날,아임포트)

본인인증을 하려면 등록해야할것들이 많다

https://m.blog.naver.com/PostView.nhn?blogId=iamport&logNo=221004352427&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F

pg사 를 다날로 가입 후 아임포트 연동까지해놓았다는 전제로 시작하겠다

https://docs.iamport.kr/tech/mobile-authentication

이쪽으로가면 아주 친절히 설명이 되어있지만 안드로이드만해온 사용자라면 어케하라는지 이해가안갈것이다 (me)

결론은 저것들을 html파일을 안드안에 넣어놓고 안드로이드에서 웹뷰로 띄워야한다

여기서 웹뷰의 데이터를 자바로 움길 필요가있는데 자바스크립트파일을 어떻게하는지도 보자

manifests

추가

xml

kotlin

class

override fun

onCreate

super

activity_auth

fun

initWebView

//activity_auth_webView.setWebViewClient(DanalWebViewClient(this))

val

javaScriptEnabled

true //자바스크립트 필수

builtInZoomControls

true

loadWithOverviewMode

true

defaultTextEncodingName

"UTF-8"

//settings.domStorageEnabled=true //

webChromeClient

webViewClient

,

"Android"

"file:///android_asset/auth.html"

class

@android.webkit.JavascriptInterface

//

절대필수

fun

getData

//

가져올 매개변수타입 정의

AuthActivity : AppCompatActivity() {(savedInstanceState: Bundle?) {.onCreate(savedInstanceState)setContentView(R.layout.initWebView()() {settings = activity_auth_webView.getSettings()settings.settings.settings.settings.activity_auth_webView.= WebChromeClient()activity_auth_webView.= WebViewClient()activity_auth_webView.addJavascriptInterface(JsHandler())//생성한class넣고 javascript안에서 쓸 이름을 명시한다activity_auth_webView.loadUrl(JsHandler {(impUid: String) {

html파일을 만들라면 assets폴더부터 만들어야한다

app부분 오른쪽 마우스눌러서 new -folder - assets folder 누르면 assets가 생긴다

assets 폴더 오른쪽누르고 new - file눌러서

html붙여서 파일을 만든다

만든 html 파일에 아임포트 예제를 그냥 박아넣는다

IMP.init('') 이안에는 https://admin.iamport.kr/settings 이쪽 아임포트 어드민 페이지가서 로그인 후 시스템설정에 가맹점 식별코드

저 Android.getData()이부분은 위에 정의한 값이다 이안에 값을넣고 인증성공시 안드로이드로 값이 넘어간다

rsp.imp_uid는 인증성공한 유저의 인증키이다 (가변) 이 값을 이용해 아임포트의 인증정보를 조회해서 가져와보자

(아임포트 본인인증설명 사이트에서는 ajax로 다처리하는데 저리하고프면 저리해도된다) 나는 retrofit 쓸래

https://api.iamport.kr/

여기로 가면

certifications:SMS본인인증결과 조회 및 관리가 있을것이다 이것을 쓸것인데

이것을 쓰기위해서 일단 인증을해야한다(authenticate) 인증을 위해서는 imp_key와 imp_secret가 필요하다

(이것은 https://admin.iamport.kr/settings 로긴후 시스템설정안에 있다 )

retrofit 셋팅

gradle

'com.squareup.retrofit2:retrofit:2.1.0'

'com.squareup.retrofit2:converter-gson:2.1.0'

public interface

/*

본인인증

*/

@POST

"/users/getToken"

token

@Body

;

@GET

"/certifications/{imp_uid}"

certification_by_imp_uid

@Header

"Authorization"

,

@Path

"imp_uid"

;

implementationimplementationIamportClient {)//인증할때 쓸것Call AuthData auth))//나의 인증정보 가져올때 쓸것Call ) String token) String imp_uid

domain

data class

@SerializedName

"imp_key"

var

api_key

null,

@SerializedName

"imp_secret"

var

api_secret

null

data class

@SerializedName

"code"

var

code

,

@SerializedName

"message"

var

message

,

@SerializedName

"response"

var

response

data class

@SerializedName

"access_token"

var

accessToken

,

@SerializedName

"now"

var

now

,

@SerializedName

"expired_at"

var

expiredAt

data class

@SerializedName

"code"

var

code

,

@SerializedName

"message"

var

message

,

@SerializedName

"response"

var

response

data class

@SerializedName

"imp_uid"

var

impUid

,

@SerializedName

"merchant_uid"

var

merchantUid

,

@SerializedName

"pg_tid"

var

pgTid

,

@SerializedName

"pg_provider"

var

pgProvider

,

@SerializedName

"name"

var

name

,

@SerializedName

"gender"

var

gender

,

@SerializedName

"birth"

var

birth

,

@SerializedName

"foreigner"

var

foreigner

,

@SerializedName

"certified"

var

certified

,

@SerializedName

"certified_at"

var

certifiedAt

,

@SerializedName

"unique_key"

var

uniqueKey

,

@SerializedName

"unique_in_site"

var

uniqueInSite

,

@SerializedName

"origin"

var

origin

AuthData(:String?=:String?=AccessToken(: Int?: Any?: AccessTokenResponse?AccessTokenResponse(: String?: Int?: Int?Certification (: Int?: String?: CertificationResponse?CertificationResponse(: String?: String?: String?: String?: String?: String?: Int?: Boolean?: Boolean?: Int?: String?: String?: String?

아까 만든 class JsHandler에 retrofit 추가하자

아임포트 웹뷰의 본인인증 키를 가지고있고(impUid)

아임포트 api 의 인증토큰을 얻어서 (iamportClient.token)

웹뷰의 본인인증키를 가지고 인증정보를 얻는다 (iamportClient.certification_by_imp_uid)

class

val

API_URL

"https://api.iamport.kr"

var

retrofit

var

iamportClient

init

retrofit

API_URL

iamportClient

retrofit

class

java

@android.webkit.JavascriptInterface

//

절대필수

fun

getData

impUid

val

iamportAPiKey

val

iamportAPiSecretKey

val

iamportClient

,

object

override fun

onResponse

,

if

isSuccessful

println

"

토큰은

?

${

response

response

accessToken

}

"

var

response

response

accessToken

var

iamportClient

,

impUid

object

override fun

onResponse

,

if

isSuccessful

println

"

인증정보

${

response

response

}

"

override fun

onFailure

,

override fun

onFailure

,

//

가져올 매개변수타입 정의

JsHandler {: Retrofit: IamportClient= Retrofit.Builder().baseUrl().addConverterFactory(GsonConverterFactory.create()).build().create(IamportClient::: String) {apiKey: String = Resources.getSystem().getString(R.string.apiSecretKey: String = Resources.getSystem().getString(R.string.getData =.token(AuthData(apiKeyapiSecretKey))getData.enqueue(: Callback {(call: Call ?response: Response ?) {(response!!.) {.body().?.token =.body().?.getAuth =.certification_by_imp_uid(tokengetAuth.enqueue(: Callback {(call: Call ?response: Response ?) {(response!!.) {.body().(call: Call ?t: Throwable?) {})(call: Call ?t: Throwable?) {})

[안드로이드] 파이어베이스 전화번호 인증 구현 방법

300x250

SMALL

[2021-05-16 업데이트]

오랜만에 안드로이드 관련 포스팅입니다.

복습도 할겸 이전에 했던 프로젝트를 보던 중 전화번호 인증 구현에 대해 포스팅을 해보려고합니다.

안드로이드와 코틀린을 요즘 못하고있네요 ㅠㅠ

공식문서를 참고했습니다.

firebase.google.com/docs/auth/android/phone-auth?hl=ko

추가로 제가 여기서 구현한 전화번호인증을 구현하려면 이미 파이어베이스 인증이 된 상태여야 합니다. 저 같은 경우 이 화면의 이전 로직에서 파이어베이스 이메일 로그인 인증을 한 상태이고 추가적으로 전화번호 인증을 한겁니다.

파이어베이스 auth 로그인 인증이 안된 경우 제가 구현한 전화번호 인증에서 전화번호를 onVerificationCompleted() 로 콜백으로 받을 수 없는 것 같습니다. 이를 위해서는 onCodeSent() 에서 별도의 auth 인증하는 추가로직이 필요하고 공식문서를 참고하시거나 이 포스팅의 마지막 하단에 추가내용을 확인하시면 될 것 같습니다.

먼저 결과 영상부터 보면 다음과 같습니다.

프로젝트가 파이어베이스와 연결이 되어있고 다음과 같이 auth 관련 디펜던시가 추가되어있는 상태여야 합니다.

또한, 파이어베이스 콘솔에서 인증 방법 선택에서 전화번호인증을 on 해주어야함을 잊지마세염.

implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' implementation 'com.google.firebase:firebase-auth:19.3.2' implementation 'com.google.firebase:firebase-auth-ktx:19.3.2' implementation 'com.google.firebase:firebase-messaging:20.2.4' implementation 'com.google.firebase:firebase-storage:19.2.0' implementation 'com.google.firebase:firebase-storage-ktx:19.2.0' implementation 'com.google.firebase:firebase-database:19.4.0' implementation 'com.google.firebase:firebase-database-ktx:19.4.0'

그리고 SHA 지문도 등록해줘야합니다

밑은 구현해야하는 전화번호 화면이었습니다. 처음에는 인증번호 입력 칸이 disabled 되어 있고 휴대폰번호 입력 후 인증요청을 하면 성공적으로 전화번호 인증코드 수신이 완료되면 인증번호 입력칸이 abled 되어서 칠 수 있게 했습니다. (참고로 사진상으로는 순서가 바뀌어있습니다.)

추가로, 전화번호 인증요청은 4번 이상정도 계속 요청하면 몇시간이나 하루동안은 인증요청이 안됩니다. (장난 요청으로 취급해서 구글에서 차단해버리기 때문이죠) 그래서 실제번호로 인증요청 테스트할때 조심하셔야합니다. 테스트 번호로 하는 방법도 문서에 작성되어있습니다.

테스트 번호 예제(전화번호와 인증코드를 미리 세팅할 수 있다.)

구현한 화면과 로직

[먼저 액티비티단 코드입니다. 이 액티비티에서 문자열을 따로 strings.xml로 빼지는 않았었네요.]

1. callbacks 가 전화번호 인증을 수신하는 객체입니다. 저 같은 경우 이 화면에 오기전에 이미 파이어베이스 이메일 로그인이 된 상태이므로 onCodeSent()로 로그인 하는 추가 로직 없이 onVertificationCompleted() 를 통해 바로 SMS 인증번호를 받을 수 있었습니다.

추가적으로 설명하면

onVerificationCompleted() 은 번호인증 혹은 기타 다른 인증(구글로그인, 이메일로그인 등) 끝난 상태

onVerificationFailed() 은 번호인증 실패 상태

onCodeSent() 은 전화번호는 확인 되었으나 인증코드를 입력해야 하는 상태

입니다.

2. initViewModelCallback() 에서 requestAuth 를 observe하는 부분이 인증번호 요청을 눌렀을때입니다. 구글 파이어베이스 전화번호 인증은 전세계에서 사용하기 때문에 앞에 국가번호가 붙습니다. 이를 사용자가 직접입력하게 해도 되지만 전 편의성을 위해 사용자는 10-1234-5567 식으로 입력하게 안내하고 제가 앞에 +82를 붙여서 전화번호 요청을 했습니다.

3.

package com.mtjin.nomoneytrip.views.phone import android.content.Intent import android.os.Bundle import android.util.Log import androidx.lifecycle.Observer import com.google.firebase.FirebaseException import com.google.firebase.auth.PhoneAuthCredential import com.google.firebase.auth.PhoneAuthProvider import com.mtjin.nomoneytrip.R import com.mtjin.nomoneytrip.base.BaseActivity import com.mtjin.nomoneytrip.databinding.ActivityPhoneAuthBinding import com.mtjin.nomoneytrip.views.login.LoginActivity import com.mtjin.nomoneytrip.views.main.MainActivity import org.koin.androidx.viewmodel.ext.android.viewModel import java.util.concurrent.TimeUnit class PhoneAuthActivity : BaseActivity(R.layout.activity_phone_auth) { private val viewModel: PhoneAuthViewModel by viewModel() private val callbacks by lazy { object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() { override fun onVerificationCompleted(phoneAuth: PhoneAuthCredential) { showToast("인증코드가 전송되었습니다. 60초 이내에 입력해주세요 :)") viewModel.authNum = phoneAuth.smsCode.toString() binding.etEnterCode.isEnabled = true binding.tvAuthNext.isEnabled = true binding.etPhone.isEnabled = true viewModel.updateAuthState(true) } override fun onVerificationFailed(p0: FirebaseException) { showToast("인증실패") binding.etPhone.isEnabled = true Log.d(com.mtjin.nomoneytrip.utils.TAG, p0.toString()) } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding.vm = viewModel initViewModelCallback() } private fun initViewModelCallback() { with(viewModel) { requestAuth.observe(this@PhoneAuthActivity, Observer { Log.d(com.mtjin.nomoneytrip.utils.TAG, viewModel.etPhoneNum.toString()) if (it) { PhoneAuthProvider.getInstance().verifyPhoneNumber( "+82" + viewModel.etPhoneNum.value.toString(), // Phone number to verify 60, // Timeout duration TimeUnit.SECONDS, // Unit of timeout this@PhoneAuthActivity, // Activity (for callback binding) callbacks ) // OnVerificationStateChangedCallbacks binding.etPhone.isEnabled = false } else { binding.etPhone.error = getString(R.string.please_enter_phone_err) } }) resultAuthUser.observe(this@PhoneAuthActivity, Observer { success -> if (!success) { showToast("인증실패") } else { startActivity(Intent(this@PhoneAuthActivity, MainActivity::class.java)) showToast("인증성공") finish() } }) backClick.observe(this@PhoneAuthActivity, Observer { startActivity(Intent(this@PhoneAuthActivity, LoginActivity::class.java)) finish() }) } } }

[다음은 ViewModel 코드입니다.]

네 평범한 뷰모델 코드입니다. 레포지토리 부분은 따로 다루지 않겠습니다.

package com.mtjin.nomoneytrip.views.phone import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.mtjin.nomoneytrip.base.BaseViewModel import com.mtjin.nomoneytrip.data.phone.source.PhoneAuthRepository import com.mtjin.nomoneytrip.utils.SingleLiveEvent import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.subscribeBy import io.reactivex.schedulers.Schedulers class PhoneAuthViewModel(private val repository: PhoneAuthRepository) : BaseViewModel() { lateinit var authNum: String //문자로온 인증번호 var tel: String = "" val etPhoneNum = MutableLiveData("") val etAuthNum = MutableLiveData("") private val _requestAuth = SingleLiveEvent() private val _authState = MutableLiveData() //인증번호 요청 했는지 유무 private val _resultAuthUser = MutableLiveData() val requestAuth: LiveData get() = _requestAuth val authState: LiveData get() = _authState val resultAuthUser: LiveData get() = _resultAuthUser fun requestAuth() { _requestAuth.value = !etPhoneNum.value.isNullOrBlank() } fun updateAuthState(boolean: Boolean) { _authState.value = boolean tel = etPhoneNum.value.toString() } fun authUser() { if (this::authNum.isInitialized && authNum == etAuthNum.value.toString()) { updateUserTel() } else { _resultAuthUser.value = false } } private fun updateUserTel() { compositeDisposable.add( repository.updateUserTel(tel = tel) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { showProgress() } .doAfterTerminate { hideProgress() } .subscribeBy( onError = { _resultAuthUser.value = false }, onComplete = { _resultAuthUser.value = true } ) ) } }

[마지막으로 xml 코드입니다. 데이터 바인딩처리가 되어있습니다.]

파이어베이스 덕분에 쉽게 전화번호 인증을 구현할 수 있었습니다. 그리고 인증번호 요청 메시지도 본인이 커스텀할 수 있습니다. (전 기본은 영어로되어있는데 한국어로만 변경해주었습니다.)

[빠진 추가내용]

https://console.cloud.google.com/apis/library/androidcheck.googleapis.com

다음 사이트에서 내 프로젝트의 Android Device Verificaiton을 사용 수락해야합니다.

[파이어베이스 인증이 안되어있는 경우 onCodeSent() 를 사용한 전화번호 인증 및 로그인]

파이어베이스 로그인 인증이 안되어있는 경우 위에서 구현한 것 처럼 onVerificationCompleted() 로 바로 인증번호를 알 수 없습니다. 이를 위해 onCodeSent() 와 인증하는 로직을 더해서 구현해야합니다.

단계를 먼저 간단히 설명하면

1. startPhoneNumberVerification() 를 통해 전화번호 인증코드를 요청한다.

2. Callbacks의 onCodeSent()에서 인증ID(verificationId) 와 토큰(token, 재전송시 사용)을 얻고 나중에 사용하기 위해 변수에 저장해놓는다.

3. 2에서 받은 인증ID와 메시지로 받은 인증코드를 사용해(매칭해) PhoneAuthCredential을 생성하고 verifyPhoneNumberWithCode() 를 통해 인증 로그인을 시도한다.

또한 참고로 전화번호 인증은 한 기기당 할당량이 있기 때문에 여러번 테스트가 불가합니다.(문자가안옴)

그래서 파이어베이스 인증에서 전화를 클릭 후 밑과 같이 테스트 전화번호를 입력해서 테스트하길 권장드립니다. 전화번호와 보낼 인증코드를 미리적으면 됩니다.

이 번호를 사용 시 문자메시지는 안오고 그냥 저 번호의 인증코드를 입력하면 됩니다. (문자메시지 안온다고 에러가아니고 원래 테스트번호이기 때문에 안오는 겁니다. 주의!!)

코드에 주석을 적어놨고 이해하실 수 있으리라 믿습니다. ㅎㅎ

[레포지토리 코드]

https://github.com/OnzeGgaaziFlow/EnvironmentMate-Android/blob/main/app/src/main/java/com/mtjin/envmate/views/sign_up/phone_auth/PhoneAuthActivity.kt

[디자인] [간단요약버전] [Activity]

package com.mtjin.envmate.views.sign_up.phone_auth import android.content.Intent import android.os.Bundle import android.util.Log import androidx.activity.viewModels import androidx.core.content.ContextCompat import androidx.lifecycle.Observer import com.google.firebase.FirebaseException import com.google.firebase.FirebaseTooManyRequestsException import com.google.firebase.auth.* import com.google.firebase.auth.ktx.auth import com.google.firebase.ktx.Firebase import com.mtjin.envmate.R import com.mtjin.envmate.base.BaseActivity import com.mtjin.envmate.databinding.ActivityPhoneAuthBinding import com.mtjin.envmate.utils.TAG import com.mtjin.envmate.views.sign_up.user_info.UserInfoActivity import dagger.hilt.android.AndroidEntryPoint import java.util.concurrent.TimeUnit @AndroidEntryPoint class PhoneAuthActivity : BaseActivity(R.layout.activity_phone_auth) { private lateinit var auth: FirebaseAuth private var storedVerificationId = "" private var resendToken: PhoneAuthProvider.ForceResendingToken? = null private val viewModel: PhoneAuthViewModel by viewModels() private val callbacks by lazy { object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() { // 번호인증 혹은 기타 다른 인증(구글로그인, 이메일로그인 등) 끝난 상태 override fun onVerificationCompleted(credential: PhoneAuthCredential) { // This callback will be invoked in two situations: // 1 - Instant verification. In some cases the phone number can be instantly // verified without needing to send or enter a verification code. // 2 - Auto-retrieval. On some devices Google Play services can automatically // detect the incoming verification SMS and perform verification without // user action. showToast("인증코드가 전송되었습니다. 90초 이내에 입력해주세요 :)") verifyPhoneNumberWithCode(credential) } // 번호인증 실패 상태 override fun onVerificationFailed(e: FirebaseException) { // This callback is invoked in an invalid request for verification is made, // for instance if the the phone number format is not valid. Log.w(TAG, "onVerificationFailed", e) if (e is FirebaseAuthInvalidCredentialsException) { // Invalid request } else if (e is FirebaseTooManyRequestsException) { // The SMS quota for the project has been exceeded } showToast("인증실패") } // 전화번호는 확인 되었으나 인증코드를 입력해야 하는 상태 override fun onCodeSent( verificationId: String, token: PhoneAuthProvider.ForceResendingToken ) { // The SMS verification code has been sent to the provided phone number, we // now need to ask the user to enter the code and then construct a credential // by combining the code with a verification ID. Log.d(TAG, "onCodeSent:$verificationId") // Save verification ID and resending token so we can use them later storedVerificationId = verificationId // verificationId 와 전화번호인증코드 매칭해서 인증하는데 사용예정 resendToken = token } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialize Firebase Auth auth = Firebase.auth binding.vm = viewModel initViewModelCallback() } private fun initViewModelCallback() { with(viewModel) { requestPhoneAuth.observe(this@PhoneAuthActivity, Observer { // 인증번호 요청 if (it) { viewModel.phoneAuthNum = "" startPhoneNumberVerification( "+82" + viewModel.etPhoneNum.value.toString().substring(1) ) } else { showToast("전화번호를 입력해주세요") } }) requestResendPhoneAuth.observe(this@PhoneAuthActivity, Observer { // 인증번호 재요청 if (it) { viewModel.phoneAuthNum = "" resendVerificationCode( "+82" + viewModel.etPhoneNum.value.toString().substring(1) , resendToken ) } else { showToast("전화번호를 입력해주세요") } }) authComplete.observe(this@PhoneAuthActivity, Observer { // 인증완료 버튼 클릭 시 // 휴대폰 인증번호로 인증 및 로그인 실행 // onCodeSent() 에서 받은 vertificationID 와 문자메시지로 전송한 인증코드값으로 Credintial 만든 후 인증 시도 val phoneCredential = PhoneAuthProvider.getCredential( storedVerificationId, viewModel.etAuthNum.value!! ) verifyPhoneNumberWithCode(phoneCredential) }) } } // 전화번호 인증코드 요청 private fun startPhoneNumberVerification(phoneNumber: String) { val options = PhoneAuthOptions.newBuilder(auth) .setPhoneNumber(phoneNumber) // Phone number to verify .setTimeout(90L, TimeUnit.SECONDS) // Timeout and unit .setActivity(this) // Activity (for callback binding) .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks .build() PhoneAuthProvider.verifyPhoneNumber(options) binding.phoneAuthBtnAuth.run { text = "재전송" setTextColor( ContextCompat.getColor( this@PhoneAuthActivity, R.color.dark_gray_333333 ) ) background = ContextCompat.getDrawable( this@PhoneAuthActivity, R.drawable.bg_btn_stroke_dark_gray_333333_radius_8dp ) } } // 전화번호 인증코드 재요청 private fun resendVerificationCode( phoneNumber: String, token: PhoneAuthProvider.ForceResendingToken? ) { val optionsBuilder = PhoneAuthOptions.newBuilder(auth) .setPhoneNumber(phoneNumber) // Phone number to verify .setTimeout(90L, TimeUnit.SECONDS) // Timeout and unit .setActivity(this) // Activity (for callback binding) .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks if (token != null) { optionsBuilder.setForceResendingToken(token) // callback's ForceResendingToken } PhoneAuthProvider.verifyPhoneNumber(optionsBuilder.build()) } // 전화번호 인증 실행 (onCodeSent() 에서 받은 vertificationID 와 // 문자로 받은 인증코드로 생성한 PhoneAuthCredential 사용) private fun verifyPhoneNumberWithCode(phoneAuthCredential: PhoneAuthCredential) { Firebase.auth.signInWithCredential(phoneAuthCredential) .addOnCompleteListener(this@PhoneAuthActivity) { task -> if (task.isSuccessful) { Log.d(TAG, "signInWithCredential:success") showToast("인증 성공") startActivity( Intent(this@PhoneAuthActivity, UserInfoActivity::class.java) ) } else { binding.phoneAuthTvAuthNum.text = getString(R.string.auth_num_wrong_text) binding.phoneAuthTvAuthNum.setTextColor( ContextCompat.getColor(this@PhoneAuthActivity, R.color.red_FF5050) ) } } } }

[ViewModel]

package com.mtjin.envmate.views.sign_up.phone_auth import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.mtjin.envmate.base.BaseViewModel import com.mtjin.envmate.utils.SingleLiveEvent import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel class PhoneAuthViewModel @Inject constructor() : BaseViewModel() { var phoneAuthNum: String = "" var isResendPhoneAuth: Boolean = false val etPhoneNum = MutableLiveData("") val etAuthNum = MutableLiveData("") private val _requestPhoneAuth = MutableLiveData() private val _requestResendPhoneAuth = MutableLiveData() private val _authComplete = SingleLiveEvent() val requestPhoneAuth: LiveData get() = _requestPhoneAuth val requestResendPhoneAuth: LiveData get() = _requestResendPhoneAuth val authComplete: LiveData get() = _authComplete fun requestPhoneAuth() { if (!isResendPhoneAuth) { //첫 폰인증 _requestPhoneAuth.value = !etPhoneNum.value.isNullOrBlank() } else { //재시도 _requestResendPhoneAuth.value = !etPhoneNum.value.isNullOrBlank() } } fun authComplete() { _authComplete.call() } }

[이후 필요한 로직 추가한 버전] [Activity]

package com.mtjin.envmate.views.sign_up.phone_auth import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import androidx.activity.viewModels import androidx.core.content.ContextCompat import androidx.lifecycle.Observer import com.google.firebase.FirebaseException import com.google.firebase.FirebaseTooManyRequestsException import com.google.firebase.auth.* import com.google.firebase.auth.ktx.auth import com.google.firebase.ktx.Firebase import com.mtjin.envmate.R import com.mtjin.envmate.base.BaseActivity import com.mtjin.envmate.databinding.ActivityPhoneAuthBinding import com.mtjin.envmate.utils.TAG import com.mtjin.envmate.utils.UserInfo import com.mtjin.envmate.views.sign_up.user_info.UserInfoActivity import dagger.hilt.android.AndroidEntryPoint import java.util.concurrent.TimeUnit @AndroidEntryPoint class PhoneAuthActivity : BaseActivity(R.layout.activity_phone_auth) { private lateinit var auth: FirebaseAuth private var storedVerificationId = "" private var resendToken: PhoneAuthProvider.ForceResendingToken? = null private val viewModel: PhoneAuthViewModel by viewModels() private val callbacks by lazy { object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() { // 번호인증 혹은 기타 다른 인증(구글로그인, 이메일로그인 등) 끝난 상태 override fun onVerificationCompleted(credential: PhoneAuthCredential) { // This callback will be invoked in two situations: // 1 - Instant verification. In some cases the phone number can be instantly // verified without needing to send or enter a verification code. // 2 - Auto-retrieval. On some devices Google Play services can automatically // detect the incoming verification SMS and perform verification without // user action. showToast("인증코드가 전송되었습니다. 90초 이내에 입력해주세요 :)") UserInfo.phoneAuthNum = credential.smsCode.toString() binding.phoneAuthEtAuthNum.setText(credential.smsCode.toString()) binding.phoneAuthEtAuthNum.isEnabled = false Handler(Looper.getMainLooper()).postDelayed({ verifyPhoneNumberWithCode(credential) }, 1000) } // 번호인증 실패 상태 override fun onVerificationFailed(e: FirebaseException) { // This callback is invoked in an invalid request for verification is made, // for instance if the the phone number format is not valid. Log.w(TAG, "onVerificationFailed", e) if (e is FirebaseAuthInvalidCredentialsException) { // Invalid request } else if (e is FirebaseTooManyRequestsException) { // The SMS quota for the project has been exceeded } showToast("인증실패") } // 전화번호는 확인 되었으나 인증코드를 입력해야 하는 상태 override fun onCodeSent( verificationId: String, token: PhoneAuthProvider.ForceResendingToken ) { // The SMS verification code has been sent to the provided phone number, we // now need to ask the user to enter the code and then construct a credential // by combining the code with a verification ID. Log.d(TAG, "onCodeSent:$verificationId") // Save verification ID and resending token so we can use them later storedVerificationId = verificationId // verificationId 와 전화번호인증코드 매칭해서 인증하는데 사용예정 resendToken = token } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialize Firebase Auth auth = Firebase.auth binding.vm = viewModel initViewModelCallback() } private fun initViewModelCallback() { with(viewModel) { requestPhoneAuth.observe(this@PhoneAuthActivity, Observer { // 인증번호 요청 UserInfo.tel = viewModel.etPhoneNum.value.toString() // 전화번호 저장 if (it) { startPhoneNumberVerification( "+82" + viewModel.etPhoneNum.value.toString().substring(1) ) } else { showToast("전화번호를 입력해주세요") } }) requestResendPhoneAuth.observe(this@PhoneAuthActivity, Observer { // 인증번호 재요청 if (it) { resendVerificationCode( "+82" + viewModel.etPhoneNum.value.toString().substring(1) , resendToken ) } else { showToast("전화번호를 입력해주세요") } }) authComplete.observe(this@PhoneAuthActivity, Observer { // 인증완료 버튼 클릭 시 // 휴대폰 인증번호로 인증 및 로그인 실행 // onCodeSent() 에서 받은 vertificationID 와 문자메시지로 전송한 인증코드값으로 Credintial 만든 후 인증 시도 try { val phoneCredential = PhoneAuthProvider.getCredential( storedVerificationId, viewModel.etAuthNum.value!! ) verifyPhoneNumberWithCode(phoneCredential) } catch (e: Exception) { Log.d(TAG, e.toString()) } }) } } // 전화번호 인증코드 요청 private fun startPhoneNumberVerification(phoneNumber: String) { val options = PhoneAuthOptions.newBuilder(auth) .setPhoneNumber(phoneNumber) // Phone number to verify .setTimeout(90L, TimeUnit.SECONDS) // Timeout and unit .setActivity(this) // Activity (for callback binding) .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks .build() PhoneAuthProvider.verifyPhoneNumber(options) binding.phoneAuthBtnAuth.run { text = "재전송" setTextColor( ContextCompat.getColor( this@PhoneAuthActivity, R.color.dark_gray_333333 ) ) background = ContextCompat.getDrawable( this@PhoneAuthActivity, R.drawable.bg_btn_stroke_dark_gray_333333_radius_8dp ) } } // 전화번호 인증코드 재요청 private fun resendVerificationCode( phoneNumber: String, token: PhoneAuthProvider.ForceResendingToken? ) { val optionsBuilder = PhoneAuthOptions.newBuilder(auth) .setPhoneNumber(phoneNumber) // Phone number to verify .setTimeout(90L, TimeUnit.SECONDS) // Timeout and unit .setActivity(this) // Activity (for callback binding) .setCallbacks(callbacks) // OnVerificationStateChangedCallbacks if (token != null) { optionsBuilder.setForceResendingToken(token) // callback's ForceResendingToken } PhoneAuthProvider.verifyPhoneNumber(optionsBuilder.build()) } // 전화번호 인증 실행 (onCodeSent() 에서 받은 vertificationID 와 // 문자로 받은 인증코드로 생성한 PhoneAuthCredential 사용) private fun verifyPhoneNumberWithCode(phoneAuthCredential: PhoneAuthCredential) { UserInfo.tel = binding.phoneAuthEtPhoneNum.text.toString() if (UserInfo.tel.isNotBlank() && UserInfo.phoneAuthNum.isNotBlank() && (UserInfo.tel == binding.phoneAuthEtPhoneNum.text.toString() && UserInfo.phoneAuthNum == binding.phoneAuthEtAuthNum.text.toString()) ) { // 이전에 인증한 번호와 인증번호인 경우 showToast("인증 성공") UserInfo.tel = binding.phoneAuthEtPhoneNum.text.toString() startActivity(Intent(this@PhoneAuthActivity, UserInfoActivity::class.java)) return } Firebase.auth.signInWithCredential(phoneAuthCredential) .addOnCompleteListener(this@PhoneAuthActivity) { task -> if (task.isSuccessful) { showToast("인증 성공") UserInfo.tel = binding.phoneAuthEtPhoneNum.text.toString() binding.phoneAuthEtAuthNum.isEnabled = true startActivity( Intent(this@PhoneAuthActivity, UserInfoActivity::class.java) ) } else { binding.phoneAuthTvAuthNum.text = getString(R.string.auth_num_wrong_text) binding.phoneAuthTvAuthNum.setTextColor( ContextCompat.getColor(this@PhoneAuthActivity, R.color.red_FF5050) ) binding.phoneAuthEtAuthNum.isEnabled = true } } } }

[ViewModel]

package com.mtjin.envmate.views.sign_up.phone_auth import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.mtjin.envmate.base.BaseViewModel import com.mtjin.envmate.utils.SingleLiveEvent import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel class PhoneAuthViewModel @Inject constructor() : BaseViewModel() { var isResendPhoneAuth: Boolean = false val etPhoneNum = MutableLiveData("") val etAuthNum = MutableLiveData("") private val _requestPhoneAuth = MutableLiveData() private val _requestResendPhoneAuth = MutableLiveData() private val _authComplete = SingleLiveEvent() val requestPhoneAuth: LiveData get() = _requestPhoneAuth val requestResendPhoneAuth: LiveData get() = _requestResendPhoneAuth val authComplete: LiveData get() = _authComplete fun requestPhoneAuth() { if (!isResendPhoneAuth) { //첫 폰인증 _requestPhoneAuth.value = !etPhoneNum.value.isNullOrBlank() //isResendPhoneAuth = true } else { //재시도 _requestResendPhoneAuth.value = !etPhoneNum.value.isNullOrBlank() } } fun authComplete() { _authComplete.call() } }

댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!

300x250

LIST

휴대폰번호 로그인 개발자센터

개발 가이드

연동 가이드

Server(Web)

Android

iOS

1. 개요 휴대폰번호 로그인은 OAuth2.0 기반의 사용자 인증 기능과 PASS 앱을 통한 간편 본인 인증 기능을 통해 제휴사에서 보다 안전하고 편리하게 사용자 인증을 할 수 있도록 하는 서비스 입니다. 제휴사 서비스를 이용하는 사용자는 별도의 아이디나 비밀번호를 기억할 필요 없이 휴대폰번호와 PASS인증앱으로 인증하여 안전하게 로그인할 수 있습니다.

2. 개발환경 및 구성요소 빌드 환경 Java Version 1.8 이상

Gradle Version 4.6

Gradle Plugin Version 3.2.1

(com.android.tools.build:bradle:3.2.1)

(com.android.tools.build:bradle:3.2.1) Min SDK Version 16

(Android 4.1.1 JellyBean)

(Android 4.1.1 JellyBean) Compile SDK Version 28

(Android 9.0 Pie) 실행 환경 Android Version 4.1.1

(API 16 JellyBean) 이상 안드로이드 권한 Android.permission.INTERNET 제공 파일 Android용 휴대폰번호 로그인 라이브러리는 android_sdk_{version}.aar로 전달 ProGuard 설정 시 유의사항 제휴사 애플리케이션에서 ProGuard를 사용할 경우 설정 내 휴대폰번호 로그인 라이브러리는 제외해 주셔야 합니다. 설정 예제 buildTypes{ release { minifyEnabled true proguardFile getDefaultProguardFile('proguard-android.txt') proguardFile 'proguard-passlogin.pro' } } proguard-passlogin.pro 내용 -keep class kr.co.atsolutions.passloginthirdparty.** { *; }

3. 적용 절차 3.1 애플리케이션 등록 제휴사 앱 서비스에 휴대폰번호 로그인을 적용하기 위해서는 해당 앱을 휴대폰번호 로그인 서비스에 등록하고 클라이언트 아이디와 클라이언트 시크릿을 발급 받아야 합니다. 3.2 애플리케이션 개발 제휴사 앱 서비스에 5. 라이브러리 적용 가이드를 통해 라이브러리 추가하고 6. API 명세, 7. 개발 가이드를 참고하여 개발 후 테스트 및 검증을 진행 합니다.

이때 서비스 검증을 위한 PASS 앱은 별도로 제공 됩니다.

4. OAuth2.0 인증 절차 제휴사에서 OAuth2.0 기반의 휴대폰번호 로그인 서비스를 제공하고자 할 때 제휴사 앱과 PASS앱, 휴대폰번호 로그인 서버 사이에 인증을 요청하고 접근 토큰(access_token)을 획득하는 과정 및 사용자 정보를 조회하는 개략의 과정은 다음과 같습니다. 4.1 접근코드 획득 사용자가 애플리케이션에서 휴대폰번호 로그인으로 로그인을 시도 할 때 애플리케이션은 Pass앱에 OAuth2.0 인증을 요청합니다. PASS 앱은 간편 로그인 프로세스를 거쳐 인증 여부를 애플리케이션의 URL Scheme을 통해 애플리케이션에 반환합니다. 인증 완료 후, 인증 코드 획득에 성공하면 휴대폰번호 로그인 서버에서 접근 토큰을 받아옵니다. 서버 호출 결과를PassLoginThirdPartyHandler 클래스의 run() 메소드를 통해 호출 성공 여부를 판단합니다.

만일 제휴사 앱이 실행되는 모바일 기기에 PASS 앱이 설치되어 있지 않은 경우, PASS 앱 설치 안내 페이지로 이동합니다. 4.2 사용자 정보 조회 획득한 접근 토큰을 이용하여 회원가입/수정 등에 제휴사 추가 서비스 적용에 필요한 사용자 정보를 획득할 수 있습니다. 서버 호출 결과를PassLoginThirdPartyHandler 클래스의 run() 메소드를 통해 호출 성공 여부를 판단합니다.

5. 라이브러리 적용 가이드 휴대폰번호 로그인 서비스를 이용하려는 애플리케이션에 라이브러리(PassLogin SDK)를 적용하는 방법에 대해서 기술합니다. [1. Android studio File -> Project Structure] Android Studio 상단 메뉴에서 File - Project Structure 메뉴를 선택합니다. [2. 왼쪽 상단에 + 클릭] Project Structure에서 왼쪽 상단에 + 버튼(New Module)을 클릭합니다. [3. New Module에서 import .JAR/.AAR Package 선택] New Module 팝업창에서 를 선택합니다. [4. .aar 파일을 선택하여 ok] 휴대폰번호 로그인의 SDK인 pass_login.aar 파일을 선택하여 File name에 파일 경로를 설정한 후 Finish 합니다. [5. 1~4 완료 후 다시 Android Studiod File -> Project Structure 클릭] 1 ~ 4 완료 후 Android Studio 상단메뉴에서 다시 File - Project Structure 메뉴를 선택합니다. [6. passlogin클릭 -> 하단 + 클릭 -> 3 Module dependency 클릭] Project Structure에서 왼쪽의 Modules 중 pass_login을 선택한 상태에서 하단의 + 버튼을 눌러 <3 Module dependency>를 클릭합니다. [7. Choose Modules에 :app 선택] Choose Modules 팝업 창에서 :app 을 선택합니다. [8. app Dependencies 에서 3 Module dependency 선택] Project Structure에서 왼쪽의 Modules 중 app을 선택한 상태에서 상단의 Dependencies를 선택한 후, 하단의 + 버튼을 눌러 <3 Module dependency>를 클릭합니다. [9. :passlogin선택] Choose Modules 팝업 창에서 :pass_login을 선택합니다. [10. 목록에 :passlogin 확인하면 적용 완료] [Project Structure에서 왼쪽의 Modules 중 app을 선택한 상태에서 상단의 Dependencies를 선택 한 후, 목록에서 pass_login 추가되어 있는지 확인합니다. [11. 프로젝트 목록에서 추가된 passlogin 확인] 마지막으로 Android Studio에서 왼쪽에 Project 목록에서 앱 프로젝트 내에 pass_login 모듈이 추가되어 있는지를 확인합니다. [12. 필수 의존성 라이브러리 Import 확인] implementation 'io.reactivex.rxjava2:rxjava:2.2.7' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.squareup.retrofit2:retrofit:2.6.4' implementation 'com.squareup.retrofit2:converter-gson:2.6.4' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.4' implementation 'com.squareup.okhttp3:okhttp:3.4.1' implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1' implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.google.android.gms:play-services-gcm:17.0.0'

6. 라이브러리 API 6.1 getInstance 설명 휴대폰번호 로그인으로 로그인 인스턴스(싱글턴 인스턴스)를 반환합니다. 구문 /*! * PassLoginThirdPartyConnection 인스턴스 * @param context context * @return PassLoginThirdPartyConnection */ public static PassLoginThirdPartyConnection getInstance(Context context) 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 context context Y SharedPreference에 접근하기 위한 Conext객체 반환값 PassLoginThirdPartyConnection 객체. 싱글턴 패턴을 이용해 PassLoginThirdPartyConnection 객체를 새로 생성해 반환하거나 기존에 생성했던 객체를 반환합니다. 코드 예시 mConnection = PassLoginThirdPartyConnection.getInstance(BaseActivity.this); 6.2 init 설명 휴대폰번호 로그인 인스턴스 PassLoginThirdPartyConnection 객체에 SDK 에서 필요한 클라이언트 정보를 설정합니다. 구문 /*! * 휴대폰번호 로그인 하기 위한 데이터 초기화 * @param context context * @param clientId Client Id * @param clientSecret Client Secret * @param appName 앱 이름 * @param callbackUrl callbackUrl */ public void init(Context context, String clientId, String clientSecret, String appName, String callbackUrl) 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 context Conext Y SharedPreference에 접근하기 위한 Conext객체 clientId String Y 휴대폰번호 로그인 서버에서 발급받은 client id clientSecret String Y 휴대폰번호 로그인 서버에서 발급받은 client secret appName String Y 제휴사 앱 이름 callbackUrl String Y 애플리케이션 등록할 때 설정한 Package Name 반환값 없음 코드예시 mConnection.init(BaseActivity.this, mClientId, mClientSecret, mAppName, mCallbackUrl); 6.3 통신사별 설정 설명 통신사 별 설정 객체를 생성합니다. 6.3.1 setUrl 구문 public void setUrl(String url); 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 url String Y 고정값(https://id.passlogin.com) 반환값 없음 코드예시 mPreference= new PassLoginThirdPartyPreference(this); mPreference.setUrl(url); 6.3.2 setTeleType 설명 Deprecated Method. SDK내에서 수행 됨. (설정 불필요) 구문 public String setTeleType(String teleType); 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 teleType String Y 요청 통신사 타입

- S: SK텔레콤

- K: KT

- L: LG유플러스 반환값 없음 코드예시 mPreference.setTeleType(teleType); 6.3.3 setCarrierUrlScheme 설명 Deprecated Method. SDK내에서 수행 됨. (설정 불필요) 구문 public String setCarrierUrlScheme(Context context, String packageName, String scheme, String host); 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 context Context Y SharedPreference에 접근하기 위한 Context객체 packageName String Y 요청 통신사 package name

- 제휴사 개별 유선 요청 필요합니다.([email protected]) scheme String Y 요청 통신사 scheme

- 제휴사 개별 유선 요청 필요합니다.([email protected]) host String Y 요청 통신사 pass host

- 제휴사 개별 유선 요청 필요합니다.([email protected]) 반환값 없음 코드예시 mConnection.setCarrierUrlScheme(MainActivity.this, packageName, scheme, host); 6.4 setPassLoginHandler 설명 로그인, 로그아웃, 로그인 ID 요청, 연동해제, 사용자정보조회 요청이 완료되면 해당 결과를 콜백 받을 핸들러를 지정합니다. 구문 /*! * 핸들러 설정 * @param handler PassLoginThirdPartyHandler */ public void setPassLoginHandler(PassLoginThirdPartyHandler handler) 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 passLoginThirdPartyHandler PassLoginThirdPartyHandler Y 로그인, 로그아웃, 로그인 ID 요청, 연동해제, 사용자정보조회 요청이 완료되면 해당 결과를 콜백 받을 핸들러를 지정합니다. 핸들러에 관한 자세한 내용은 7.1PassLoginHandler를 참고합니다. 반환값 없음 코드예시 mConnection.setPassLoginHandler(mPassLoginHandler); 6.5 getVersion 설명 PassLoginThirdParty.aar의 버전을 반환합니다. 구문 /*! * 휴대폰번호 Login SDK 버전 조회 * @return version 버전 */ public String getVersion() 파라미터 없음 반환값 1.x.x 형식으로 된 문자열 코드 예시 mConnection.getVersion() 6.6 getState 설명 현재 휴대폰번호 로그인 인증 상태를 PassLoginThirdPartyState의 enum 객체(상수값)로 반환합니다. getState에 대해서 상수, 설명으로 분류되어 내용을 제공하는 테이블 상수 설명 NEED_INIT = 0 PassLoginThirdParty 초기화 필요 NEED_LOGIN = 1 휴대폰번호 로그인 인증 필요 OK = 2 휴대폰번호 로그인 인증 완료 구문 /*! * 휴대폰번호 로그인 인증 상태 조회 * NEED_INIT(0) : PassLoginThirdParty 초기화 필요, NEED_LOGIN(1): 휴대폰번호 로그인 인증 필요, OK (2) : 휴대폰번호 로그인 인증 완료 * @return PassLoginThirdPartyState enum 값 */ public PassLoginThirdPartyState getState() 파라미터 없음 반환값 PassLoginThirdPartyState의 enum객체를 반환합니다. 코드 예시 if(mConnection.getState() == PassLoginThirdPartyState.NEED_INIT) { } else if(mConnection.getState() == PassLoginThirdPartyState.NEED_LOGIN) { } else if(mConnection.getState() == PassLoginThirdPartyState.OK) { } 6.7 getAccessToken 설명 휴대폰번호 로그인 결과로 얻은 access token 을 반환합니다. 구문 /*! * access token 조회 * @return access token */ public String getAccessToken() 파라미터 없음 반환값 접근 토큰 코드 예시 mConnection.getAccessToken(); 6.8 getAccessTokenExpireDate 설명 access token 의 만료 시간을 반환합니다. 구문 /*! * access token 만료시간 조회 * @return access token 만료시간 (UTC Time : millisecond 단위) */ public long getAccessTokenExpireDate() 파라미터 없음 반환값 Date 타입의 접근 토큰 만료 시간 (UTC time) 코드 예시 mConnection.getAccessTokenExpireDate(); 6.9 getTokenType 설명 휴대폰번호 로그인 결과로 얻은 토큰 타입 문자열을 반환합니다. 구문 /*! * token type 조회 * @return token type */ public String getTokenType() 파라미터 없음 반환값 토큰 타입 문자열

유효하지 않은 접근 토큰인 경우 null 반환 코드 예시 mConnection.getTokenType(); 6.10 requestLogin 설명 휴대폰번호 로그인으로 로그인 인증을 요청합니다. setPassLoginHandler로 지정한 핸들러를 통해 결과 값을 처리합니다. 구문 /*! * 휴대폰번호 로그인 인증 요청 * @param activity 액티비티 */ public void requestLogin(final Activity activity) 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 activity Activity Y 화면 이동시 필요한 경우(제3자 정보제공동의 웹뷰) 사용할 activity 반환값 없음 코드 예시 if(mConnection.getState() == PassLoginThirdPartyState.NEED_LOGIN) { mConnection.requestLogin(LoginActivity.this); } 6.11 requestAutoLogin 설명 PASS로그인으로 자동 로그인 인증을 요청합니다. setPassLoginHandler로 지정한 핸들러를 통해 결과 값을 처리합니다. 구문 public void requestAutoLogin(final Activity activity, String autoLoginYn, String prompt) 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 activity Activity Y 화면 이동시 필요한 경우(제3자 정보제공동의 웹뷰) 사용할 activity autoLoginYn String Y 자동로그인 사용 여부 (Y: 사용, N: 미사용) prompt String Y 자동로그인 기능 제어

- select_account: 자동로그인 및 SSO기능 제공, 최초 로그인 후 PASS 앱 인증 없이 로그인

- login: 자동로그인 기능 및 SSO기능 미제공, 항상 PASS 앱을 통한 인증 수행 반환값 없음 코드 예시 if(mConnection.getState() == PassLoginThirdPartyState.NEED_LOGIN) { mConnection.requesAutotLogin(LoginActivity.this, “Y”, “select_account”); } 6.12 requestLogout 설명 애플리케이션에 저장된 토큰 정보를 삭제합니다. setPassLoginHandler로 지정한 핸들러를 통해 결과 값을 처리합니다. 구문 /*! * 휴대폰번호 로그아웃 요청 */ public void requestLogout() 파라미터 없음 반환값 없음 코드 예시 mConnection.requestLogout(); 6.13 requestDisconnect 설명 휴대폰번호 로그인 연동을 해제하는 것으로 애플리케이션에 저장된 사용자 정보와 휴대폰번호 로그인 서버에 저장된 인증 정보를 삭제합니다. setPassLoginHandler로 지정한 핸들러를 통해 결과 값을 처리합니다. 구문 /*! * 휴대폰번호 로그인 연결 해제 요청 * 휴대폰번호 Login 서버 및 preference에서 access token 삭제 * @return 인증 해제 요청 결과 완료 여부 */ public boolean requestDisconnect() 파라미터 없음 반환값 없음 코드 예시 if(mConnection.getState() == PassLoginThirdPartyState.OK) { mConnection.requestDisconnect(); } 6.14 requestUserInfo 설명 인증 완료한 사용자의 정보를 조회할 수 있습니다. requestUserInfo()는 최초 1회만 요청할 수 있습니다. 그 이후에는 requestLoginId()를 통해 사용자의 로그인 ID를 가져올 수있습니다. setPassLoginHandler로 지정한 핸들러를 통해 결과 값을 처리합니다. 구문 /*! * 휴대폰번호 로그인 사용자 정보 요청 ( access token 발급 후 1회만 가능 이후에는 로그인 ID 조회 ) */ public void requestUserInfo() 파라미터 없음 반환값 없음 코드 예시 if(mConnection.getState() == PassLoginThirdPartyState.OK) { mConnection.requestUserInfo(); } 6.15 requestLoginId 설명 인증 완료한 사용자의 로그인ID를 조회할 수 있습니다. setPassLoginHandler로 지정한 핸들러를 통해 결과 값을 처리합니다. 구문 /*! * 휴대폰번호 로그인 ID 조회 */ public void requestLoginId() 파라미터 없음 반환값 없음 코드 예시 if(mConnection.getState() == PassLoginThirdPartyState.OK) { mConnection.requestLoginId(); }

7. 개발 가이드 7.1 PassLoginThirdPartyHandler 설명 PassLoginThirdPartyHandler 클래스의 인스턴스를 만들어 run() 메서드를 구현합니다. 생성된 인스턴스를 setPassLoginHandler() 메서드를 통해 파라메터를 전달하면 인스턴스의 run() 메소드로 들어온 응답 데이터를 통해 결과값을 처리합니다.

requestLogin(), requestLogout(), reqeustUserInfo(), reqeustLoginId(), reqeustDisconnect() API 요청에 대한 결과값을 PassLoginThirdPartyHandler 인스턴스의 run() 메소드로 받아 처리한다. 구문 /*! * requestLogin(), requestLogout(), reqeustUserInfo(), reqeustLoginId(), reqeustDisconnect()에 대한 API를 실행하고, 응답 결과를 받아 처리한다. * @param code 핸들러 상수 * @param success 요청 결과 성공 여부 (true: 성공, false: 실패) * @param response BaseResponse 응답 데이터 */ public abstract void run(int code, boolean success, BaseResponse response); 파라미터 파라미터에 대해서 파라미터, 타입, 필수여부, 설명으로 분류되어 내용을 제공하는 테이블 파라미터 타입 필수여부 설명 code int Y 로그인, 로그아웃, 연동해제, 사용자 정보 조회에 따른 PassLoginThirdPartyHandler에 정의된 상수값 isSuccess boolean Y 각 요청 결과 성공 여부(true: 성공, false: 실패) response BaseResponse N isSucess가 false인경우 BaseResponse 클래스에 있는 getErrorCode()와 getErrorDesc() 메소드를 통해 에러 처리.

사용자 정보 조회 요청 결과인 경우 response를 UserInfoResponse 클래스로 받아 사용자 정보 데이터 저장. 반환값 없음 코드 예시 protected PassLoginThirdPartyHandler mPassLoginHandler = new PassLoginThirdPartyHandler() { @Override public void run(int code, boolean isSuccess, BaseResponse response) { switch (code) { case PassLoginThirdPartyHandler.REQUEST_CODE_LOGIN: //제휴사 앱 로그인 인증처리 //6.13 requestUserInfo 또는 6.14 requestLoginId 호출 break; case PassLoginThirdPartyHandler.REQUEST_CODE_GET_USER_INFO: //제휴사 앱 사용자 정보 조회 break; case PassLoginThirdPartyHandler.REQUEST_CODE_GET_LOGIN_ID //제휴사 앱 로그인 ID 조회 break; case PassLoginThirdPartyHandler.REQUEST_CODE_DISCONNECT: //제휴사 앱 탈퇴 처리 break; case PassLoginThirdPartyHandler.REQUEST_CODE_LOGOUT: //제휴사 앱 로그아웃 처리 break; } } }; *참고 PassLoginThirdPartyHandler에 대해서 상수값 정의, 설명으로 분류되어 내용을 제공하는 테이블 상수값 정의 설명 BaseResponse 응답 데이터 PassLoginThirdPartyHandler.REQUEST_CODE_LOGIN requestLogin()를 통해 얻은 휴대폰번호 로그인 으로 로그인 요청한 결과 7.2 AccessTokenResponse 참고 PassLoginThirdPartyHandler.REQUEST_CODE_LOGOUT requestLogout()을 통해 로그아웃 요청한 결과 PassLoginThirdPartyHandler.REQUEST_CODE_GET_USER_INFO reqeustUserInfo ()를 통해 사용자 정보 요청한 결과 7.3 UserInforesponse 참고 PassLoginThirdPartyHandler.REQUEST_CODE_GET_LOGIN_ID requestUserId()를 통해 사용자 로그인 ID 요청한 결과 7.4 LoginIdResponse 참고 PassLoginThirdPartyHandler.REQUEST_CODE_DISCONNECT reqeustDisconnect ()를 통해 휴대폰번호 로그인 연동 해제 요청한 결과 7.2 AccessTokenResponse 설명 requestLogin() 호출 시 PassLoginThirdPartyHandler로 수신되는 BaseResponse 객체.

METHOD METHOD 반환타입 설명 getAccessToken() String 접근 토큰 getTokenType() String 토큰의 접근 타입(Bearer) getExpireDate() String 접근 토큰의 만료시간(초) getState() String CSRF 공격을 방지하기 위해 사용하는 클라이언트 측 인증값(URL인코딩) 7.3 UserInfoResponse 설명 requestUserInfo() 호출 시 PassLoginThirdPartyHandler로 수신되는 BaseResponse 객체.

METHOD METHOD 반환타입 설명 getUser() User 유저정보 반환(7.5 User 참고) 7.4 LoginIdResponse 설명 requestUserId() 호출 시 PassLoginThirdPartyHandler로 수신되는 BaseResponse 객체.

METHOD METHOD 반환타입 설명 getPlid() String PASS 사용자 식별 정보 7.5 User 설명 PASS 앱에서 전달받은 유저정보.

METHOD METHOD 반환타입 설명 getPlid() String PASS 사용자 식별 정보 getCi() String 사용자 식별 정보(암호화) getName() String PASS 사용자 이름(암호화) getPhoneNo() String PASS 사용자 휴대전화번호(암호화) getGender() String PASS 사용자 성별(F: 여자, M: 남자) getAgeGroup() String PASS 사용자 연령대(0, 10, 20, 30 ….)

0: 0세 ~ 10세 미만

10: 10세 ~ 20세 미만

20: 20세 ~ 30세 미만

... getBirthday() String PASS 사용자 생일(암호화)

(MMDD) getBirthdate() String PASS 사용자 생년월일(암호화)

(YYMMDD) getForeign() String PASS 사용자 내외국인정보

(L: 내국인, F: 외국인) getAutoLoginYn() String 자동로그인 사용자 여부

(Y: 사용, N: 미사용) getAutoStatusCheck() String 자동로그인 접속 체크

(Y: 최초 자동로그인, N: 최초이거나, 미사용자)

NICE아이디

휴대폰본인확인

휴대폰 보급률 110%의 대한민국

가장 편리하고 보편화된

본인확인 서비스를 소개합니다.

본인 명의의 휴대폰인지와 해당 휴대폰을 보유하고 있는지

동시에 확인하는 본인확인 서비스 입니다.

본인확인 결과로 통신사에 등록된 명의자 정보와 휴대폰번호를

수집할 수 있어, 회원가입 등 본인확인이 필요한 업무에

보편적으로 사용하는 서비스 입니다.

돈 1원도 안쓰고 공짜로 폰번호 문자 인증 서비스 만들기

728x90

반응형

요즘 나오는 앱서비스들을 보면 폰번호 인증을 위해서

사용자가 입력한 폰번호로 SMS를 6자리의 숫자코드를 포함하여 보내고

그 값을 입력하게 하여 폰번호를 인증하는 절차를 넣는 경우가 대부분입니다.

이 기능 자체를 구현하는것은 사실 크게 어려움이 있는 것은 아닙니다.

다만 SMS 발송을 위한 여러 절차들이 꽤나 번거롭고 귀찮은 일입니다.

SMS 발송을 위해 SMS 발송업체와 계약 절차를 진행해야되고,

세금계산서 발행을 해야하고,

SMS를 보낼수 있는 잔액이 충분히 있는지 주기적으로 체크를 해주어야 합니다.

게다가 SMS 제공업체의 서비스가 살아있는지도 확인할수 있어야하고,

새로운 업체와 계약을 할때마다 api document를 읽고 새로 만들어야하는것도 일입니다.

그리고 물론 기쁜 일이지만,

사용자가 늘면 늘수록 문자비용도 점점 늘어나게되지요.

이러한 고민을 쉽게 해결할수 있도록 해주는 유용한 서비스가 있습니다.

facebook account kit이라고 불리는 서비스입니다.

페이스북에서 제공하는 sdk인데 꽤나 유용합니다.

실제로 전세계적으로 많은 앱들이 사용하고 있습니다.

사실 이러한 무료 SDK를 적용할때 가장 고민되는 부분중에 하나는

"UI, UX 커스터마이징이 되나? 우리 앱에 자연스럽게 녹아들었으면 좋겠는데?"

물론 100% 만족할수는 없습니다.

약간의 완벽한 UI, UX를 포기하는 대신에

다른 관리적인 측면에서의 장점을 얻으실수 있습니다. 비용적인 측면을 포함해서요.

https://developers.facebook.com/success-stories

여기에 나와있는 많은 회사들이 쓰고 있으니

다른 앱에서 얼만큼 자연스럽게 쓰고 있는지 비교해보시는 것도 좋습니다.

그래도 다행인건 인증과정은 페이스북이 제공하는 UI, UX를 사용해야 하지만

그 UI에 페이스북 로고가 큼지막하게 박혀있다거나 그렇지는 않습니다.

그리고 약간의 색상 커스터마이징이 가능합니다.

사용에 있어서 장점은 더 무궁무진하게 많습니다.

1. 지원되는 국가가 많습니다.

적어도 페이스북이 지원하고 있는 국가는 모두 다 지원한다고 봐도 되겠죠?

2. 문자 수신이 안정적입니다.

저는 동남아시아 지역에서 현지 업체의 SMS API를 사용하기도 했었는데

실제 문자 수신률이 들쑥날쑥하더군요

그래서 문자인증을 통과하지 못해 가입과정에서 많은 이탈률을 보았는데

페이스북 어카운트킷을 적용하고는 훨씬 나아졌습니다.

3. 비용이 들지 않습니다.

100% 무료는 아니고 월 100,000건의 발송량 제한이 있습니다만

이정도면 매우 훌륭합니다.

여러분이 한건에 약 11원씩 문자를 발송하고 있다고치면

월 10만건을 보내는 경우 약 110만원의 비용이 드는건데

이 비용을 절감하실수 있습니다.

4. 여러가지의 인증보조도구를 제공합니다.

문자메시지를 통한 인증이 가능하고,

문자를 수신하지 못하였을때

사용자가 직접 전화를 수신하여 인증을 할 수 있는 보조수단을 제공하고 있습니다.

그리고 현재는 지원이 되는것 같지는 않지만

조만간 왓츠앱을 통한 인증도 자동으로 포함하게될것 같습니다.

그리고 이미 사용자가 같은 폰에 페이스북을 설치하였고,

페이스북 로그인이 되어있는 계정에 인증받은 폰번호가 있다면

별도의 인증과정을 거치지 않고 자동적으로 인증이 완료됩니다.

이같은 장점만 보아도 사용할만한 충분한 메리트가 있지 않나요?

인증하는 과정에서 발송되는 인증코드 번호를 앱제공자가 알수 있거나 지정할 수는 없지만

최종적으로 인증을 받은 폰번호를 전달받게되기 때문에 큰 불편함은 없습니다.

오히려 인증번호를 생성하는 과정은 굳이 만들지 않아도되서 더욱 편합니다.

대략적으로 중요한 부분은 위와 같습니다.

accountkit이 노출될 액티비티를 android manifest파일에 적어주어야하고

해당 액티비티에 적용될 스타일을 만들어 정의하면 됩니다.

적용할수 있는 스타일 이름값들은

https://developers.facebook.com/docs/accountkit/android/customizing

여기에 자세하게 정리되어있습니다.

한가지 주의할 점은 SDK 매뉴얼에 언급되어있지는 않지만

implementation "com.google.android.gms:play-services-auth:16.0.0"

이것을 포함하셔야지 빌드할때 에러가 발생하지 않습니다.

그럼 즐거운 개발하시길바랍니다.

728x90

반응형

[웹개발일기] 휴대폰 본인인증 구현하기

[가이드] 휴대폰 본인인증

휴대폰 본인인증 연동하기 휴대폰 본인인증 서비스란 본인 명의로 개통한 휴대폰을 이용하여 최소한의 개인정보를 입력하는 인증 절차를 거쳐 본인 여부와 입력한 정보의 정확성을 확인하여

docs.iamport.kr

휴대폰 본인인증 성공 후 인증 정보 취득 · Issue #7 · iamport/iamport_flutter

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Pick a username Email Address Password Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

키워드에 대한 정보 안드로이드 휴대폰 인증 소스

다음은 Bing에서 안드로이드 휴대폰 인증 소스 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 이게 켜져 있으면 내 정보 밤새 다 빠져나갑니다!! 휴대폰 설정 4가지 무조건 꺼 놓으세요!

  • 개인정보유출
  • 해킹
  • 휴대폰설정

이게 #켜져 #있으면 #내 #정보 #밤새 #다 #빠져나갑니다!! #휴대폰 #설정 #4가지 #무조건 #꺼 #놓으세요!


YouTube에서 안드로이드 휴대폰 인증 소스 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 이게 켜져 있으면 내 정보 밤새 다 빠져나갑니다!! 휴대폰 설정 4가지 무조건 꺼 놓으세요! | 안드로이드 휴대폰 인증 소스, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

Leave a Comment