如何防止同一用户从不同设备登录?我的应用已付款,因此我不希望共享凭据

时间:2017-04-12 04:47:37

标签: java firebase firebase-authentication

我是firebase的新手,但我设法使用firebase开发应用程序 - 电子邮件和密码验证 这个应用程序适用于组织的成员,所以没有在应用程序上注册,组织给我一个列表,我添加到用户列表。我的问题是,我只有45个注册用户,但几乎有85谁正在使用该应用程序。我明白我应该使用身份验证令牌,但我不太清楚。任何人都可以解释我可以同时防止多次登录的最简单方法吗? 我已经附加了登录代码(我尝试存储设备名称,但这是一种不好的方式)所以有人可以帮我解决必须做的事情吗?

public class EmailLogin extends AppCompatActivity implements
        View.OnClickListener {
    public String  Email;
    private static final String TAG = "EmailPassword";
public  static  int  device = 0;
    private TextView forgoPwd;
    private TextView mDetailTextView;
    private EditText mEmailField;
    private EditText mPasswordField;
    private ProgressDialog PD;
    private CheckBox saveLoginCheckBox;
    private SharedPreferences loginPreferences;
    private SharedPreferences.Editor loginPrefsEditor;
    private Boolean saveLogin;
    // [START declare_auth]
    private FirebaseAuth mAuth;
    // [END declare_auth]
    private DatabaseReference root;
    // [START declare_auth_listener]
    private FirebaseAuth.AuthStateListener mAuthListener;
    // [END declare_auth_listener]
    private String  temp_key;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.emailpass);


        PD = new ProgressDialog(this);
        PD.setMessage("Loading...");
        PD.setCancelable(true);
        PD.setCanceledOnTouchOutside(false);
        // Views

        mEmailField = (EditText) findViewById(R.id.field_email);
        Email = mEmailField.toString();
        mPasswordField = (EditText) findViewById(R.id.field_password);
        Button btnCount = (Button) findViewById(R.id.email_sign_in_button);
       // Button regis = (Button) findViewById(R.id.regis);
        saveLoginCheckBox = (CheckBox)findViewById(R.id.checkBox);
        loginPreferences = getSharedPreferences("loginPrefs", MODE_PRIVATE);
        loginPrefsEditor = loginPreferences.edit();
        saveLogin = loginPreferences.getBoolean("saveLogin", false);
        if (saveLogin == true) {
            mEmailField.setText(loginPreferences.getString("username", ""));
            mPasswordField.setText(loginPreferences.getString("password", ""));
            saveLoginCheckBox.setChecked(true);
        }


        //regis.setOnClickListener(this);
        forgoPwd = (TextView)findViewById(R.id.forgo);
        forgoPwd.setOnClickListener(this);
        // Buttons
        btnCount.setOnClickListener(this);
        //  findViewById(R.id.email_create_account_button).setOnClickListener(this);
        //   findViewById(R.id.sign_out_button).setOnClickListener(this);

        // [START initialize_auth]
        mAuth = FirebaseAuth.getInstance();
        // [END initialize_auth]

        // [START auth_state_listener]
        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    // User is signed in
                   Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
                } else {
                    // User is signed out
                    Log.d(TAG, "onAuthStateChanged:signed_out");
                }
                // [START_EXCLUDE]
                updateUI(user);
                // [END_EXCLUDE]
            }
        };
        // [END auth_state_listener]
    }


    public ProgressDialog mProgressDialog;

    public void showProgressDialog() {
        if (mProgressDialog == null) {
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setMessage(getString(R.string.loading));
            mProgressDialog.setIndeterminate(true);
        }
    }
    public void hideProgressDialog() {
        if (mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }
    // [START on_start_add_listener]
    @Override
    public void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthListener);
    }
    // [END on_start_add_listener]

    // [START on_stop_remove_listener]
    @Override
    public void onStop() {
        super.onStop();
        if (mAuthListener != null) {
            mAuth.removeAuthStateListener(mAuthListener);
        }
    }
    // [END on_stop_remove_listener]

    private void createAccount(String email, String password) {
        Log.d(TAG, "createAccount:" + email);
        if (!validateForm()) {
            return;
        }

        showProgressDialog();

        // [START create_user_with_email]
        mAuth.createUserWithEmailAndPassword(email, password)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());

                        // If sign in fails, display a message to the user. If sign in succeeds
                        // the auth state listener will be notified and logic to handle the
                        // signed in user can be handled in the listener.
                        if (!task.isSuccessful()) {
                            Toast.makeText(EmailLogin.this, R.string.auth_failed,
                                    Toast.LENGTH_SHORT).show();
                        }

                        // [START_EXCLUDE]
                        hideProgressDialog();
                        // [END_EXCLUDE]
                    }
                });
        // [END create_user_with_email]
    }

    private void signIn(String email, String password) {
        Log.d(TAG, "signIn:" + email);
        if (saveLoginCheckBox.isChecked()) {
            loginPrefsEditor.putBoolean("saveLogin", true);
            loginPrefsEditor.putString("username", mEmailField.getText().toString());
            loginPrefsEditor.putString("password", password);
            loginPrefsEditor.commit();
        } else {
            loginPrefsEditor.clear();
            loginPrefsEditor.commit();
        }
        if (!validateForm()) {
            return;
        }
        PD.show();
        showProgressDialog();

        // [START sign_in_with_email]
        mAuth.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        Log.d(TAG, "signInWithEmail:onComplete:" + task.isSuccessful());
                        if (task.isSuccessful())
                        {
                            onAuthSuccess(task.getResult().getUser());
                        }
                        // If sign in fails, display a message to the user. If sign in succeeds
                        // the auth state listener will be notified and logic to handle the
                        // signed in user can be handled in the listener.
                        if (!task.isSuccessful()) {
                            Log.w(TAG, "signInWithEmail:failed", task.getException());
                            Toast.makeText(EmailLogin.this, R.string.auth_failed,
                                    Toast.LENGTH_SHORT).show();
                        }

                        // [START_EXCLUDE]
                        if (!task.isSuccessful()) {

                            //    mStatusTextView.setText(R.string.auth_failed);
                        }PD.dismiss();
                        hideProgressDialog();
                        // [END_EXCLUDE]
                    }
                });
        // [END sign_in_with_email]
    }
    private void onAuthSuccess(FirebaseUser user) {

        if (device == 0)
getDeviceName();
        device++;
        String username = usernameFromEmail(user.getEmail());
        Intent intent = new Intent(getApplicationContext(),Home_screen.class);
        intent.putExtra("user",username);
        startActivity(intent);
        finish();
    }
    public String getDeviceName() {
        String manufacturer = Build.MANUFACTURER;
        String model = Build.MODEL;
        root = FirebaseDatabase.getInstance().getReference().child("users");
        doDb(manufacturer);
    return manufacturer+model ;
    }

    private void doDb(String manu) {
        Map<String,Object> map = new HashMap<String, Object>();
        temp_key = root.push().getKey();
        root.updateChildren(map);
        DatabaseReference mess_root = root.child(temp_key);
        Map<String,Object> map2 = new HashMap<String, Object>();
        String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
        int index = email.indexOf('@');
        email = email.substring(0,index);
        map2.put("user",email);
        map2.put("msg",manu);
        mess_root.updateChildren(map2);


    }




    private String usernameFromEmail(String email) {
        if (email.contains("@")) {
            return email.split("@")[0];
        } else {
            return email;
        }
    }
    private void signOut() {
        mAuth.signOut();
        updateUI(null);
    }

    private boolean validateForm() {
        boolean valid = true;

        String email = mEmailField.getText().toString();
        if (TextUtils.isEmpty(email)) {
            mEmailField.setError("Required.");
            valid = false;
        } else {
            mEmailField.setError(null);
        }

        String password = mPasswordField.getText().toString();
        if (TextUtils.isEmpty(password)) {
            mPasswordField.setError("Required.");
            valid = false;
        } else {
            mPasswordField.setError(null);
        }

        return valid;
    }

    private void updateUI(FirebaseUser user) {
        hideProgressDialog();
        if (user != null) {
            //Timer timer = new Timer();
            //timer.schedule(new TimerTask(){
            //    public void run() {
                    Intent i = new Intent(EmailLogin.this, Home_screen.class);
                    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(i);
                    finish();
                //    return;
              //  }
           // }, 600000);

        }
      /*
        if (user != null) {

            Intent intent = new Intent(getApplicationContext(),Home_screen.class);
            startActivity(intent);
            finish();
            mStatusTextView.setText(getString(R.string.emailpassword_status_fmt, user.getEmail()));
            mDetailTextView.setText(getString(R.string.firebase_status_fmt, user.getUid()));

            findViewById(R.id.email_password_buttons).setVisibility(View.GONE);
            findViewById(R.id.email_password_fields).setVisibility(View.GONE);

        } */



        else {
//            mStatusTextView.setText(R.string.signed_out);
            //          mDetailTextView.setText(null);

            //   findViewById(R.id.email_password_buttons).setVisibility(View.VISIBLE);
            //  findViewById(R.id.email_password_fields).setVisibility(View.VISIBLE);

        }
    }

    @Override
    public void onClick(View v) {
        int i = v.getId();

        if (i == R.id.email_sign_in_button) {
            signIn(mEmailField.getText().toString(), mPasswordField.getText().toString());
        }
        //if(i == R.id.regis)
        {

        }
        if(i == R.id.forgo) {

            FirebaseAuth auth = FirebaseAuth.getInstance();
            String mail =  mEmailField.getText().toString();
            if (TextUtils.isEmpty(mail)) {
                mEmailField.setError("Required.");

            } else {
                auth.sendPasswordResetEmail(mEmailField.getText().toString())
                        .addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    Toast.makeText(EmailLogin.this, "Email sent to your account",
                                            Toast.LENGTH_SHORT).show();
                                }
                            }
                        });
            }

        }
    }


}

2 个答案:

答案 0 :(得分:0)

  

我知道我应该使用身份验证令牌

那不行。每当用户登录设备时,他们都会获得新的身份验证令牌。因此,在两个设备上登录的同一用户将具有不同的身份验证令牌。

但他们将拥有相同的UID。所以我实际上存储了uid以及识别数据库中活动设备的东西。

activeDeviceByUser
  <uid>: <device ID>

然后在user signs outdisconnects

时将其删除

答案 1 :(得分:0)

您可以聘用会话管理器,它仅跟踪上一个会话并终止该用户的所有其他会话。一种简单的方法是在每次启动应用程序时在客户端上生成UUID(随机128位值)并将其称为sessionId。如果用户已登录,或者登录时,请将sessionId写入数据库中当前用户userId下名为lastSessionId的数据库中。然后,只需侦听当前lastSessionIduserId(在客户端)的更改即可。

当另一个客户端使用相同的userId启动您的应用程序时,该客户端也会获得一个随机的sessionId,并且该sessionId也会被写入该userId下的数据库中(覆盖最后一个客户端的写操作)。然后,向userId登录的所有客户端(通过文档侦听器)通知lastSessionId的更改,对于本地sessionId与远程{{1 }},它们的UX会得到相应处理。您可以优雅地退出这些客户端,或者更严重地终止他们的应用程序,并出现致命错误。