【问题标题】:How to validate user with respect to my Realtime Database along with OTP verification?如何根据我的实时数据库验证用户以及 OTP 验证?
【发布时间】:2018-03-16 06:13:40
【问题描述】:

我在 Android Studio 中创建了一个 Android 应用,并将其与 Firebase 实时数据库相关联。我已使用 Firebase 的电话身份验证和通知服务将 OTP 发送到 CUG 电话号码。然后验证它(代码如下)。

public class PhoneLogin extends AppCompatActivity {

private static final String TAG = "PhoneLogin";
private boolean mVerificationInProgress = false;
private String mVerificationId;
private PhoneAuthProvider.ForceResendingToken mResendToken;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
private FirebaseAuth mAuth;
TextView t1,t2;
ImageView i1;
EditText e1,e2;
Button b1,b2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_phone_login);

    e1 = (EditText) findViewById(R.id.Phonenoedittext); //Enter Phone no.
    b1 = (Button) findViewById(R.id.PhoneVerify);       //Send OTP button
    t1 = (TextView)findViewById(R.id.textView2Phone);   //Telling user to enter phone no.
    i1 = (ImageView)findViewById(R.id.imageView2Phone); //Phone icon
    e2 = (EditText) findViewById(R.id.OTPeditText);     //Enter OTP
    b2 = (Button)findViewById(R.id.OTPVERIFY);          //Verify OTP button
    t2 = (TextView)findViewById(R.id.textViewVerified); //Telling user to enter otp
    mAuth = FirebaseAuth.getInstance();
    mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        @Override
        public void onVerificationCompleted(PhoneAuthCredential credential) {
            // Log.d(TAG, "onVerificationCompleted:" + credential);
            mVerificationInProgress = false;
            Toast.makeText(PhoneLogin.this,"Verification Complete",Toast.LENGTH_SHORT).show();
            signInWithPhoneAuthCredential(credential);
        }

        @Override
        public void onVerificationFailed(FirebaseException e) {
            // Log.w(TAG, "onVerificationFailed", e);
            Toast.makeText(PhoneLogin.this,"Verification Failed",Toast.LENGTH_SHORT).show();
            if (e instanceof FirebaseAuthInvalidCredentialsException) {
                // Invalid request
                Toast.makeText(PhoneLogin.this,"InValid Phone Number",Toast.LENGTH_SHORT).show();
                // ...
            } else if (e instanceof FirebaseTooManyRequestsException) {
            }
        }

        @Override
        public void onCodeSent(String verificationId,
                               PhoneAuthProvider.ForceResendingToken token) {
            // Log.d(TAG, "onCodeSent:" + verificationId);
            Toast.makeText(PhoneLogin.this,"Verification code has been sent",Toast.LENGTH_SHORT).show();
            // Save verification ID and resending token so we can use them later
            mVerificationId = verificationId;
            mResendToken = token;
            e1.setVisibility(View.GONE);
            b1.setVisibility(View.GONE);
            t1.setVisibility(View.GONE);
            i1.setVisibility(View.GONE);
            t2.setVisibility(View.VISIBLE);
            e2.setVisibility(View.VISIBLE);
            b2.setVisibility(View.VISIBLE);
            // ...
        }
    };

    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            PhoneAuthProvider.getInstance().verifyPhoneNumber(
                    e1.getText().toString(),
                    60,
                    java.util.concurrent.TimeUnit.SECONDS,
                    PhoneLogin.this,
                    mCallbacks);
        }
    });

    b2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, e2.getText().toString());
            // [END verify_with_code]
            signInWithPhoneAuthCredential(credential);
        }
    });


}

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Log.d(TAG, "signInWithCredential:success");
                        startActivity(new Intent(PhoneLogin.this,NavigationDrawer.class));
                        Toast.makeText(PhoneLogin.this,"Verification Done",Toast.LENGTH_SHORT).show();
                        // ...
                    } else {
                        // Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                            Toast.makeText(PhoneLogin.this,"Invalid Verification",Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });
}
}

现在我想添加另一个验证输入的 CUG 编号。存在于我的数据库中,然后只应进行 OTP 身份验证。我的数据库如下所示:

My database

访问这个数据库的代码可以是

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference phoneNumberRef = 
rootRef.child("Employees").child(PhoneNumberenteredByUser);
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    if(dataSnapshot.exists()) {
        //do something
    } else {
        //do something else
    }
}

@Override
public void onCancelled(DatabaseError databaseError) {}
};
phoneNumberRef.addListenerForSingleValueEvent(eventListener);

另外,当我看到 Firebase 实时数据库的规则时,我注意到它不应该公开,但如果我需要将其保密,那么应该首先对用户进行身份验证,所以我需要先对用户进行身份验证通过 OTP 然后检查用户 CUG 号是否。存在于我的数据库中吗?

验证任何号码的已编辑代码。即使它不在我的数据库中:

public class PhoneLogin extends AppCompatActivity {
private static final String TAG = "PhoneLogin";
private boolean mVerificationInProgress = false;
private String mVerificationId;
private PhoneAuthProvider.ForceResendingToken mResendToken;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
private FirebaseAuth mAuth;
TextView t1,t2;
ImageView i1;
EditText e1,e2;
Button b1,b2;

//DBA1
private DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
private DatabaseReference phoneNumberRef;
String mobno;
//DBA1 End

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_phone_login);

    e1 = (EditText) findViewById(R.id.Phonenoedittext);
    b1 = (Button) findViewById(R.id.PhoneVerify);
    t1 = (TextView) findViewById(R.id.textView2Phone);
    i1 = (ImageView) findViewById(R.id.imageView2Phone);
    e2 = (EditText) findViewById(R.id.OTPeditText);
    b2 = (Button) findViewById(R.id.OTPVERIFY);
    t2 = (TextView) findViewById(R.id.textViewVerified);

    mobno=e1.getText().toString();

    //DBA2
    phoneNumberRef = rootRef.child("Employees").child(mobno);
    ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                mAuth = FirebaseAuth.getInstance();
                mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {


                    @Override
                    public void onVerificationCompleted(PhoneAuthCredential credential) {
                        // Log.d(TAG, "onVerificationCompleted:" + credential);
                        mVerificationInProgress = false;
                        Toast.makeText(PhoneLogin.this,"Verification Complete",Toast.LENGTH_SHORT).show();
                        signInWithPhoneAuthCredential(credential);
                    }

                    @Override
                    public void onVerificationFailed(FirebaseException e) {
                        // Log.w(TAG, "onVerificationFailed", e);
                        Toast.makeText(PhoneLogin.this,"Verification Failed",Toast.LENGTH_SHORT).show();
                        if (e instanceof FirebaseAuthInvalidCredentialsException) {
                            // Invalid request
                            Toast.makeText(PhoneLogin.this,"InValid Phone Number",Toast.LENGTH_SHORT).show();
                            // ...
                        } else if (e instanceof FirebaseTooManyRequestsException) {
                        }

                    }

                    @Override
                    public void onCodeSent(String verificationId,
                                           PhoneAuthProvider.ForceResendingToken token) {
                        // Log.d(TAG, "onCodeSent:" + verificationId);
                        Toast.makeText(PhoneLogin.this,"Verification code has been sent",Toast.LENGTH_SHORT).show();
                        // Save verification ID and resending token so we can use them later
                        mVerificationId = verificationId;
                        mResendToken = token;
                        e1.setVisibility(View.GONE);
                        b1.setVisibility(View.GONE);
                        t1.setVisibility(View.GONE);
                        i1.setVisibility(View.GONE);
                        t2.setVisibility(View.VISIBLE);
                        e2.setVisibility(View.VISIBLE);
                        b2.setVisibility(View.VISIBLE);
                        // ...
                    }
                };

                b1.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                                e1.getText().toString(),
                                60,
                                java.util.concurrent.TimeUnit.SECONDS,
                                PhoneLogin.this,
                                mCallbacks);
                    }
                });

                b2.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, e2.getText().toString());
                        // [END verify_with_code]
                        signInWithPhoneAuthCredential(credential);
                    }
                });



            } else {
                Toast.makeText(getApplicationContext(),"Incorrect CUG",Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    };
    phoneNumberRef.addListenerForSingleValueEvent(eventListener);
    //DBA2 End


}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        startActivity(new Intent(PhoneLogin.this,NavigationDrawer.class));
                        Toast.makeText(PhoneLogin.this,"Verification Done",Toast.LENGTH_SHORT).show();
                        // Log.d(TAG, "signInWithCredential:success");
                        //startActivity(new Intent(PhoneLogin.this,NavigationDrawer.class));
                        Toast.makeText(PhoneLogin.this,"Verification Done",Toast.LENGTH_SHORT).show();
                        // ...
                    } else {
                        // Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                            Toast.makeText(PhoneLogin.this,"Invalid Verification",Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });
}
}

【问题讨论】:

    标签: java android firebase firebase-realtime-database firebase-security


    【解决方案1】:

    很简单,

    编辑你的

    b2.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, e2.getText().toString());
                        // [END verify_with_code]
                        signInWithPhoneAuthCredential(credential);
                    }
                });
    

    与:

    b2.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
    //Write your database reference and check in the database for entered mobno.
    rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if(dataSnapshot.child(mobno).exists()){
                            PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, e2.getText().toString());
                        // [END verify_with_code]
                        signInWithPhoneAuthCredential(credential);
                        }
                        else{
                            Toast.makeText(PhoneLogin.this,"No such CUG No. found",Toast.LENGTH_SHORT).show();
                        }
                    }
    
                    @Override
                    public void onCancelled(DatabaseError databaseError) {
    
                    }
                });
    

    【讨论】:

      【解决方案2】:

      我希望这会有所帮助!我有这样的场景,但有一个解决方法。 首先,当向“Employees”添加数据时,您可以获取 userId 添加一个带有 userID 的额外节点。让我们试试这个

      DatabaseReference rootRef=FirebaseDatabase.getInstance().getReference("Employees");
      FirebaseAuth firebaseAuth;
      FirebaseUser user=firebaseAuth.getInstance().getCurrentUser();
      rootRef.child(user.getUid()).setValue(youModelClassObject);//rootRef is your database reference
      

      这意味着每个添加到“员工”的用户都会有一个带有用户 ID 的节点。现在尝试访问数据库并检查是否可以在员工下找到经过身份验证的userId。我会做以下事情..

      rootRef.addValueEventListener(new ValueEventListener() {
              @Override
              public void onDataChange(DataSnapshot dataSnapshot) {
                  for(DataSnapshot ds : dataSnapshot.getChildren()) {
      
                      Object obj=ds.getKey();                     //
      
                      Firebase user = firebaseAuth.getInstance().getCurrentUser();
                      String myId=user.getUid();
      
                      //Specify your model class here
                      ModelClass modelObject=new ModelClass();
      
                    if(Objects.equals(myId, obj.toString())) 
                          {
                               //assuming you've set getters and setters in your model class
                               modelObject.setPhone(ds.getValue(ModelClass.class).getPhone());
      
                               String myDatabasePhone=modelObject.getPhone();
                               if (myDatabasePhone!=null)
                                 {
                                   //Now call the second OTP verification method and pass 'myDatabasePhone'
                                 }                                 
      
                          }else {
                        //User not found
                        //direct them to a signup Activy
                          }
      
                  }
      
              }
      
              @Override
              public void onCancelled(DatabaseError databaseError) {
      
              }
          });`enter code here`
      

      【讨论】:

      • 它可以工作,但我想反过来做,首先它检查数据库,如果没有。在我的数据库中,那么它只用于 OTP 验证。
      • 如何先访问数据库,然后尝试进行身份验证?确保身份验证首先允许您访问数据库
      • 检查编辑,我在代码中添加了几行
      • 谢谢你,我会看的!我又问了一个问题,你能帮我吗? stackoverflow.com/questions/49356093/…
      【解决方案3】:

      不,当您尝试对用户进行身份验证时,您需要检查该用户是否存在。所以你需要先检查然后认证。您的代码看起来非常好。

      关于规则,这是真的,不应该公开。因此,只允许经过身份验证的用户在您的数据库中进行更改。

      【讨论】:

      • 但是如何合并这两个代码呢?如果没有用户的身份验证 ID,我如何将规则设为私有?
      • onDataChange() 方法中,做你的逻辑。将规则设置为".read": "auth != false",是最好的选择。
      • 它正在验证任何否。使用正确的 OTP,即使没有。不在我的数据库中。我将 onCreate() 中的身份验证代码部分剪切到 onCreate() 本身的 ValueListener 的 if(datasnapshot.exists()) 中。
      • 结果如何?
      • 任何没有。具有正确 OTP 但不在我的数据库中的正在验证。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 2020-09-18
      • 2023-03-22
      • 2019-03-27
      • 2018-09-17
      • 1970-01-01
      • 2022-01-04
      相关资源
      最近更新 更多