احراز هویت خودکار به وسیله خواندن پیامک در اندروید

یکی از نیاز هایی که امروزه اغلب اپلیکیشن ها با آن رو به رو هستند ، احراز هویت کاربر با استفاده از پیامک است . برای اینکه بتوانیم تجربه کاربری بهتری داشته باشیم یک راه حل این است که فرآیند خواندن کد از داخل پیامک و وارد کردن آن درون اپلیکیشن به صورت خودکار اتفاق بیافتد و کاربر بدون زحمت اضافی و فقط با تایید دسترسی ساده فرآیند احراز هویت رو انجام دهد .در این مقاله درباره راه حلی که به عنوان یه برنامه نویس اندروید برای پیاده سازی فرآیند بالا بدون گرفتن دسترسی اضافه داریم ، صحبت خواهیم کرد .۱ - مدیریت پیام های دریافتیبرای شروع لازم است ، کامپوننت Play Services auth رو به فایل build.gradle اضافه کنیم :implementation 'com.google.android.gms:play-services-auth:17.0.0' implementation 'com.google.android.gms:play-services-auth-api-phone:17.4.0'حالا هر زمان که درخواست دریافت کد ارسال شد ( برای مثال وقتی کار بر روی دکمه دریافت کد اعتبار سنجی کلیک کرد ) کافیه دستور زیر رو اجرا کنیم :SmsRetriever.getClient(context).startSmsUserConsent(senderPhoneNumber)مقدار senderPhoneNumber میتونه سرشماره ای باشه که منتظریم ازش پیامک دریافت بشه . اگه این مقدار مشخص نیست میتونیم مقدار null قرار دهیم .بعد از اجرای دستور بالا برای مدت ۵ دقیقه وقتی گوشی کاربر پیامکی دریافت کند ، Play services یک Intent به اپ ارسال می کند تا از کاربر اجازه دسترسی لازم دریافت بشه . البته متن پیامک باید شرایط زیر را داشته باشد :پیام باید شامل ۴-۱۰ کاراکتر باشد که حداقل یکیشون عدد باشه .پیام توسط شماره ای ارسال شده باشد که در لیست کانتکت های کاربر نباشه .اگه تو مرحله قبل شماره ی ارسال کننده را مشخص کرده باشیم ، پیام حتما باید از همون شماره برای کاربر ارسال شده باشد .خوب همونجوری که گفتیم اگه شرایط بالا وجود داشته باشه ، زمانی که پیامک دریافت شود Play services مارو با ارسال Intent با خبر میکنه و ما نیاز داریم که با یک BroadcastReceiver این مقدار رو دریافت کنیم .private val SMS_CONSENT_REQUEST = 2 private val smsVerificationReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) { val extras = intent.extras val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status when (smsRetrieverStatus.statusCode) { CommonStatusCodes.SUCCESS -> { val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT) try { startActivityForResult(consentIntent, SMS_CONSENT_REQUEST) } catch (e: ActivityNotFoundException) { // Handle the exception ... } } CommonStatusCodes.TIMEOUT -> { // Time out occurred, handle the error. } } } } } override fun onCreate(savedInstanceState: Bundle?) { // ... val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION) registerReceiver(smsVerificationReceiver, SmsRetriever.SEND_PERMISSION, intentFilter) }توضیحات کد بالا :خط ۱۲ : با استارت شدن اکتیوی با EXTRA_CONSENT_INTENT ، دیالوگِ گرفتن رضایت کاربر برای خواندن اون پیامک گرفته میشود. اکتیویتی باید در مدت زمان ۵ دقیقه ارسال بشه در غیر اینصورت TIMEOUT رخ می دهد .خط ۱۸ : میتونیم مشخص کنیم اگر TIMEOUT اتفاق افتاد اپلیکیشن چه رفتاری داشته باشد .و البته یادمون نمیره که هر زمان کارمون با این دوستمون smsVerificationReceiver تموم شد ، حتما اونو unregister کنیم :override fun () { // ... unregisterReceiver(smsVerificationReceiver) } ۲- در یافت کد از پیام ارسال شدهدر متد onActivityResult اکتیویتی می توانیم بازخورد کاربر به دیالوگ نمایش داده شده در مرحله قبل که برای دریافت اجازه خواندن پیامک، نمایش داده شده بود را بررسی کنیم . اگر مقدار RESULT_OK را داشته باشیم، کاربر به ما اجازه خواندن متن پیام رو داده و می توانیم متن پیام ارسال شده را از مقدار intent دریافت کنیم .public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { // ... SMS_CONSENT_REQUEST -> if (resultCode == Activity.RESULT_OK && data != null) { // Get SMS message content val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE) val oneTimeCode = parseOneTimeCode(message) // define this function } else { // Consent denied. User can type OTC manually. } } }در انتها کافیست پیام دریافت شده را تجزیه کرده و مقدار کد تایید را بدست بیاوریم و فیلد مورد نظر خودمون را با کد دریافتی تکمیل کنیم یا مرحله احراز هویت را با موفقیت رد کنیم . امیدوارم مطالب بالا براتون مفید بوده باشه . مشتاقم نظرتون رو درباره این پست بدونم. اگر سوالی هم دارید می تونید در قسمت نظرات بپرسید تا بتونیم راهنمایی تون کنیم .