현재 android java 로 개발된 서비스 중인 앱은 sms 인증 방식을 restful api로 서버에 요청하고,
서버에서 aws를 통해 문자를 보내주는 형식으로 전화번호 인증을 하고있다.
저번주에, vpn을 통해 과도한 문자청구가 되고, 백엔드 개발팀이 rate limiting을 통해 악의적인 유저를 블락하려고 해봤으나,
금주에도 동일한 공격이 발생했다.
그래서 FE에서 구글 sms 를 사용하기로 했다. 구글 firebase 는 recapcha 방식을 통해 악의적인 공격을 막아주기 때문이다.
전에 firebase sms auth로 sms 를 사용했을때, 트래킹이 되지않아 현재의 방식으로 개발했는데,
vpn을 쓰며 천천히 인증을 계속 돌리는 상황이 막상 닥치니 빨리 구글 인증으로 바꾸는 방식으로 회의를 마쳤다.
일단 현재 앱은 google Oauth를 사용하고 있기에, gradle 파일에 세팅은 완료 된 상태이다.
따라서, api를 쏴주던 함수만 수정하면된다.
if(parsedPhoneNumber != null){
PhoneAuthProvider.getInstance().verifyPhoneNumber(
"+"+parsedPhoneNumber,
60,
TimeUnit.SECONDS,
this,
mCallbacks);
}
해당 부분으로 실행해주고,
private void initCallback(){
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onCodeAutoRetrievalTimeOut(String verificationId) {
btnNext.setEnabled(true);
}
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
btnNext.setEnabled(true);
Log.d("onVerificationCompleted", "onVerificationCompleted:" + credential);
}
@Override
public void onVerificationFailed(FirebaseException e) {
btnNext.setEnabled(true);
Log.w("onVerificationFailed", "onVerificationFailed", e);
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Log.e("Exception:", "FirebaseAuthInvalidCredentialsException" + e);
} else if (e instanceof FirebaseTooManyRequestsException) {
Log.e("Exception:", "FirebaseTooManyRequestsException" + e);
}
}
@Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
btnNext.setEnabled(true);
Log.e("onCodeSent", "onCodeSent:" + verificationId);
Log.e("Verification code:", verificationId);
Intent intent = new Intent(getApplicationContext(), PhoneCertification.class);
intent.putExtra("parsedPhoneNumber", parsedPhoneNumber);
intent.putExtra("conuntryCd", conuntryCd);
intent.putExtra("verificationId",verificationId);
startActivity(intent);
finish();
}
};
}
콜백함수를 등록해준다.
6자리 인증하는 부분에서는
먼저 함수를 작성해주고
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(PhoneCertification.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.e("성공 :::::::::","성공했다 ::::");
} else {
String message = "Somthing is wrong, we will fix it soon...";
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
message = "Invalid code entered...";
}
Log.e("실패했다 :::::",message);
}
}
});
}
해당함수를 PhoneAuthCredential 객체를 만들고 param으로 넘겨줬다
try{
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, certification);
signInWithPhoneAuthCredential(credential);
}catch (Exception e){
Log.e("PhoneAuthCredential error ::::", String.valueOf(e));
}
RN에선 instance 를 사용하며 6자리까지 인증했던 기억이 나는데,
java에선 보내고, 해당 id 로 instance 에서 PhoneAuthCredential 객체를 생성한후, 그 객체에 대한 값을 확인하는 로직으로 돌아가는걸 알 수 있었다.
끝