کاربران را با اطلاعات کاربری ذخیره شده خود وارد سیستم کنید

از مشتری ورود به سیستم با یک ضربه برای درخواست مجوز از کاربر برای بازیابی یکی از اعتبارنامه هایی که قبلاً برای ورود به برنامه شما استفاده می کرد استفاده کنید. این اعتبارنامه‌ها می‌توانند یک حساب Google یا ترکیب نام کاربری-گذرواژه باشند که با استفاده از Chrome، تکمیل خودکار Android یا Smart Lock for Passwords در Google ذخیره کرده‌اند.

رابط کاربری ورود به سیستم با یک ضربه

هنگامی که اعتبارنامه ها با موفقیت بازیابی شدند، می توانید از آنها برای ورود بدون اصطکاک کاربر به برنامه خود استفاده کنید.

اگر کاربر هیچ اعتبارنامه‌ای را ذخیره نکرده باشد، هیچ رابط کاربری ارائه نمی‌شود و می‌توانید تجربه عادی خارج شدن از سیستم را ارائه دهید.

کجا باید از ورود به سیستم One Tap استفاده کنم؟

اگر برنامه شما از کاربران می خواهد که وارد سیستم شوند، رابط کاربری One Tap را در صفحه ورود به سیستم خود نمایش دهید. این می‌تواند مفید باشد حتی اگر از قبل دکمه «ورود به سیستم با Google» داشته باشید: از آنجایی که رابط کاربری One Tap را می‌توان طوری پیکربندی کرد که فقط اعتبارنامه‌هایی را نشان دهد که کاربر قبلاً برای ورود به سیستم استفاده کرده است، می‌تواند یادآوری برای کاربرانی باشد که به ندرت وارد سیستم می‌شوند. نحوه ورود آنها به آخرین بار و جلوگیری از ایجاد تصادفی حساب های جدید با برنامه شما.

اگر ورود به سیستم برای برنامه شما اختیاری است، از ورود به سیستم با یک ضربه در هر صفحه‌ای استفاده کنید که تجربه آن با ورود به سیستم بهبود یافته است. برای مثال، اگر کاربران می‌توانند در حالی که از سیستم خارج شده‌اند، محتوا را با برنامه شما مرور کنند، اما فقط می‌توانند نظر ارسال کنند یا پس از ورود به سیستم، موارد را به سبد خرید اضافه کنید، که زمینه معقولی برای ورود به سیستم با یک ضربه خواهد بود.

به دلایلی که در بالا ذکر شد، برنامه‌های اختیاری ورود به سیستم نیز باید از ورود با یک ضربه در صفحه ورود به سیستم خود استفاده کنند.

قبل از شروع

1. سرویس گیرنده ورود با یک ضربه را پیکربندی کنید

می‌توانید سرویس گیرنده ورود با یک ضربه را پیکربندی کنید تا کاربران با گذرواژه‌های ذخیره‌شده، حساب‌های Google ذخیره‌شده یا هریک به سیستم وارد شوند. (پشتیبانی از هر دو برای فعال کردن ایجاد حساب کاربری با یک ضربه برای کاربران جدید و ورود خودکار یا با یک ضربه برای هرچه بیشتر کاربران بازگشتی توصیه می‌شود.)

اگر برنامه شما از ورود مبتنی بر رمز عبور استفاده می‌کند، از setPasswordRequestOptions() برای فعال کردن درخواست‌های اعتبار رمز عبور استفاده کنید.

اگر برنامه شما از Google Sign-in استفاده می‌کند، از setGoogleIdTokenRequestOptions() برای فعال کردن و پیکربندی درخواست‌های رمز Google ID استفاده کنید:

  • شناسه سرویس گیرنده سرور را روی شناسه‌ای که در کنسول Google APIs ایجاد کرده‌اید، تنظیم کنید. توجه داشته باشید که این شناسه مشتری سرور شما است، نه شناسه مشتری اندروید شما.

  • مشتری را برای فیلتر کردن بر اساس حساب های مجاز پیکربندی کنید. وقتی این گزینه را فعال می‌کنید، مشتری One Tap فقط از کاربران می‌خواهد با حساب‌های Google که قبلاً استفاده کرده‌اند، وارد برنامه شما شوند. انجام این کار می‌تواند به کاربران کمک کند تا زمانی که مطمئن نیستند از قبل یک حساب دارند یا از کدام حساب Google استفاده کرده‌اند، با موفقیت وارد سیستم شوند و از ایجاد تصادفی حساب‌های جدید با برنامه شما جلوگیری می‌کند.

  • اگر می‌خواهید در صورت امکان کاربران را به‌طور خودکار وارد کنید، این ویژگی را با setAutoSelectEnabled() فعال کنید. ورود خودکار زمانی امکان پذیر است که معیارهای زیر رعایت شود:

    • کاربر دقیقاً یک اعتبار برای برنامه شما ذخیره کرده است. یعنی یک رمز عبور ذخیره شده یا یک حساب Google ذخیره شده.
    • کاربر ورود خودکار را در تنظیمات حساب Google خود غیرفعال نکرده است.
  • در حالی که اختیاری است، توصیه می‌کنیم برای بهبود امنیت ورود به سیستم و جلوگیری از حملات مجدد، قویاً از Nonce استفاده کنید. از setNonce برای درج یک nonce در هر درخواست استفاده کنید. برای پیشنهادات و جزئیات بیشتر در مورد تولید nonce، به بخش SafetyNet's Obtain a nonce مراجعه کنید.

جاوا

public class YourActivity extends AppCompatActivity {
  // ...

  private SignInClient oneTapClient;
  private BeginSignInRequest signInRequest;

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState,
                       @Nullable PersistableBundle persistentState) {
      super.onCreate(savedInstanceState, persistentState);

      oneTapClient = Identity.getSignInClient(this);
      signInRequest = BeginSignInRequest.builder()
              .setPasswordRequestOptions(PasswordRequestOptions.builder()
                      .setSupported(true)
                      .build())
              .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder()
                      .setSupported(true)
                      // Your server's client ID, not your Android client ID.
                      .setServerClientId(getString(R.string.default_web_client_id))
                      // Only show accounts previously used to sign in.
                      .setFilterByAuthorizedAccounts(true)
                      .build())
              // Automatically sign in when exactly one credential is retrieved.
              .setAutoSelectEnabled(true)
              .build();
      // ...
  }
  // ...
}

کاتلین

class YourActivity : AppCompatActivity() {
    // ...

    private lateinit var oneTapClient: SignInClient
    private lateinit var signInRequest: BeginSignInRequest

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        oneTapClient = Identity.getSignInClient(this)
        signInRequest = BeginSignInRequest.builder()
            .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder()
                .setSupported(true)
                .build())
            .setGoogleIdTokenRequestOptions(
                BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                    .setSupported(true)
                    // Your server's client ID, not your Android client ID.
                    .setServerClientId(getString(R.string.your_web_client_id))
                    // Only show accounts previously used to sign in.
                    .setFilterByAuthorizedAccounts(true)
                    .build())
            // Automatically sign in when exactly one credential is retrieved.
            .setAutoSelectEnabled(true)
            .build()
        // ...
    }
    // ...
}

2. یک کاربر وارد شده را بررسی کنید

اگر فعالیت شما می‌تواند توسط یک کاربر وارد شده یا یک کاربر خارج از سیستم استفاده شود، قبل از نمایش رابط کاربری ورود به سیستم با یک ضربه، وضعیت کاربر را بررسی کنید.

همچنین باید ردیابی کنید که آیا کاربر قبلاً از ورود به سیستم با One Tap خودداری کرده است یا با بستن اعلان یا ضربه زدن در خارج از آن. این می تواند به سادگی یک ویژگی بولی از Activity شما باشد. (به توقف نمایش رابط کاربری One Tap در زیر مراجعه کنید.)

3. رابط کاربری ورود با یک ضربه را نمایش دهید

اگر کاربر وارد نشده است و قبلاً استفاده از ورود به سیستم One Tap را نپذیرفته است، متد beginSignIn() شی مشتری را فراخوانی کرده و شنوندگان را به Task که برمی‌گرداند متصل کنید. برنامه ها معمولاً این کار را در روش Activity's onCreate() یا پس از انتقال صفحه هنگام استفاده از معماری تک فعالیت انجام می دهند.

اگر کاربر اطلاعات کاربری ذخیره شده ای برای برنامه شما داشته باشد، مشتری One Tap با شنونده موفق تماس می گیرد. در موفقیت شنونده، هدف معلق را از نتیجه Task دریافت کنید و آن را به startIntentSenderForResult() ارسال کنید تا رابط کاربری ورود به سیستم One Tap شروع شود.

اگر کاربر هیچ اعتبار ذخیره شده ای نداشته باشد، سرویس گیرنده One Tap با شنونده شکست تماس می گیرد. در این مورد، هیچ اقدامی لازم نیست: می‌توانید به سادگی به ارائه تجربه خروج از سیستم برنامه ادامه دهید. با این حال، اگر از ثبت‌نام با One Tap پشتیبانی می‌کنید، می‌توانید آن جریان را از اینجا شروع کنید تا یک تجربه ایجاد حساب کاربری یکپارچه داشته باشید. به ایجاد حساب های جدید با یک ضربه مراجعه کنید.

جاوا

oneTapClient.beginSignIn(signUpRequest)
        .addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
            @Override
            public void onSuccess(BeginSignInResult result) {
                try {
                    startIntentSenderForResult(
                            result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
                            null, 0, 0, 0);
                } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
                }
            }
        })
        .addOnFailureListener(this, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // No saved credentials found. Launch the One Tap sign-up flow, or
                // do nothing and continue presenting the signed-out UI.
                Log.d(TAG, e.getLocalizedMessage());
            }
        });

کاتلین

oneTapClient.beginSignIn(signInRequest)
    .addOnSuccessListener(this) { result ->
        try {
            startIntentSenderForResult(
                result.pendingIntent.intentSender, REQ_ONE_TAP,
                null, 0, 0, 0, null)
        } catch (e: IntentSender.SendIntentException) {
            Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
        }
    }
    .addOnFailureListener(this) { e ->
        // No saved credentials found. Launch the One Tap sign-up flow, or
        // do nothing and continue presenting the signed-out UI.
        Log.d(TAG, e.localizedMessage)
    }

4. پاسخ کاربر را مدیریت کنید

پاسخ کاربر به درخواست ورود با یک ضربه با استفاده از روش onActivityResult() Activity به برنامه شما گزارش می شود. اگر کاربر ورود به سیستم را انتخاب کند، نتیجه یک اعتبار ذخیره شده خواهد بود. اگر کاربر از ورود به سیستم خودداری کرد، چه با بستن رابط کاربری One Tap یا ضربه زدن در خارج از آن، نتیجه با کد RESULT_CANCELED برمی‌گردد. برنامه شما باید هر دو احتمال را مدیریت کند.

با اعتبارنامه های بازیابی شده وارد شوید

اگر کاربر اشتراک‌گذاری اعتبارنامه‌ها را با برنامه شما انتخاب کرد، می‌توانید با ارسال داده‌های intent از onActivityResult() به متد getSignInCredentialFromIntent() مشتری One Tap آنها را بازیابی کنید. اگر کاربر اعتبار حساب Google را با برنامه شما به اشتراک بگذارد، اعتبارنامه دارای یک ویژگی googleIdToken غیر تهی خواهد بود، یا اگر کاربر یک رمز password ذخیره شده را به اشتراک گذاشته باشد، دارای ویژگی گذرواژه غیر تهی خواهد بود.

از اعتبارنامه برای احراز هویت با باطن برنامه خود استفاده کنید.

  • اگر یک جفت نام کاربری و رمز عبور بازیابی شد، از آنها برای ورود به سیستم به همان روشی استفاده کنید که اگر کاربر به صورت دستی آنها را ارائه کرده بود.
  • اگر اعتبارنامه حساب Google بازیابی شد، از کد ID برای احراز هویت با باطن خود استفاده کنید. اگر انتخاب کرده اید که از nonce برای جلوگیری از حملات مجدد استفاده کنید، مقدار پاسخ را در سرور باطن خود بررسی کنید. احراز هویت با استفاده از رمزهای ID را ببینید.

جاوا

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(data);
                  String idToken = credential.getGoogleIdToken();
                  String username = credential.getId();
                  String password = credential.getPassword();
                  if (idToken !=  null) {
                      // Got an ID token from Google. Use it to authenticate
                      // with your backend.
                      Log.d(TAG, "Got ID token.");
                  } else if (password != null) {
                      // Got a saved username and password. Use them to authenticate
                      // with your backend.
                      Log.d(TAG, "Got password.");
                  }
              } catch (ApiException e) {
                  // ...
              }
              break;
      }
  }
}

کاتلین

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
             REQ_ONE_TAP -> {
                try {
                    val credential = oneTapClient.getSignInCredentialFromIntent(data)
                    val idToken = credential.googleIdToken
                    val username = credential.id
                    val password = credential.password
                    when {
                        idToken != null -> {
                            // Got an ID token from Google. Use it to authenticate
                            // with your backend.
                            Log.d(TAG, "Got ID token.")
                        }
                        password != null -> {
                            // Got a saved username and password. Use them to authenticate
                            // with your backend.
                            Log.d(TAG, "Got password.")
                        }
                        else -> {
                            // Shouldn't happen.
                            Log.d(TAG, "No ID token or password!")
                        }
                    }
                } catch (e: ApiException) {
                    // ...
                }
            }
        }
    }
    // ...
}

نمایش رابط کاربری One Tap را متوقف کنید

اگر کاربر ورود به سیستم را رد کرد، تماس با getSignInCredentialFromIntent() یک ApiException با کد وضعیت CommonStatusCodes.CANCELED ایجاد می کند. وقتی این اتفاق می‌افتد، باید به طور موقت رابط کاربری One Tap را غیرفعال کنید تا کاربران خود را با درخواست‌های مکرر آزار ندهید. مثال زیر این کار را با تنظیم یک ویژگی در Activity انجام می دهد، که از آن برای تعیین اینکه آیا به کاربر ورود با یک ضربه را ارائه می دهد یا خیر، استفاده می کند. با این حال، شما همچنین می توانید یک مقدار را در SharedPreferences ذخیره کنید یا از روش دیگری استفاده کنید.

این مهم است که محدودیت نرخ خود را برای درخواست‌های ورود به سیستم با یک ضربه اجرا کنید. اگر این کار را نکنید و یک کاربر چندین درخواست را پشت سر هم لغو کند، مشتری One Tap تا 24 ساعت آینده از کاربر درخواست نخواهد کرد.

جاوا

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
      super.onActivityResult(requestCode, resultCode, data);

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  // ...
              } catch (ApiException e) {
                  switch (e.getStatusCode()) {
                      case CommonStatusCodes.CANCELED:
                          Log.d(TAG, "One-tap dialog was closed.");
                          // Don't re-prompt the user.
                          showOneTapUI = false;
                          break;
                      case CommonStatusCodes.NETWORK_ERROR:
                          Log.d(TAG, "One-tap encountered a network error.");
                          // Try again or just ignore.
                          break;
                      default:
                          Log.d(TAG, "Couldn't get credential from result."
                                  + e.getLocalizedMessage());
                          break;
                  }
              }
              break;
      }
  }
}

کاتلین

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
            REQ_ONE_TAP -> {
                try {
                    // ...
                } catch (e: ApiException) {
                    when (e.statusCode) {
                        CommonStatusCodes.CANCELED -> {
                            Log.d(TAG, "One-tap dialog was closed.")
                            // Don't re-prompt the user.
                            showOneTapUI = false
                        }
                        CommonStatusCodes.NETWORK_ERROR -> {
                            Log.d(TAG, "One-tap encountered a network error.")
                            // Try again or just ignore.
                        }
                        else -> {
                            Log.d(TAG, "Couldn't get credential from result." +
                                " (${e.localizedMessage})")
                        }
                    }
                }
            }
        }
    }
    // ...
}

5. خروج از سیستم را کنترل کنید

هنگامی که کاربر از برنامه شما خارج شد، متد signOut() مشتری One Tap را فراخوانی کنید. فراخوانی signOut() ورود خودکار را غیرفعال می کند تا زمانی که کاربر دوباره وارد سیستم شود.

حتی اگر از ورود خودکار استفاده نمی‌کنید، این مرحله مهم است زیرا تضمین می‌کند وقتی کاربران از برنامه شما خارج می‌شوند، وضعیت احراز هویت هر یک از APIهای Play Services که استفاده می‌کنید نیز بازنشانی می‌شود.

مراحل بعدی

اگر سرویس گیرنده One Tap را برای بازیابی اطلاعات کاربری Google پیکربندی کرده باشید، برنامه شما اکنون می‌تواند نشانه‌های Google ID را دریافت کند که نشان‌دهنده حساب‌های Google کاربران شما هستند. بیاموزید که چگونه می توانید از این نشانه ها در باطن استفاده کنید .

اگر از Google Sign-in پشتیبانی می‌کنید، می‌توانید از سرویس گیرنده One Tap نیز برای اضافه کردن جریان‌های ایجاد حساب بدون اصطکاک به برنامه خود استفاده کنید.