هنگامی که کاربر یک حساب Google را انتخاب می کند، مشتری ورود با یک ضربه، یک نشانه Google ID را بازیابی می کند. یک نشانه شناسه تأیید امضا شده هویت کاربر است که حاوی اطلاعات اولیه نمایه کاربر، احتمالاً شامل آدرس ایمیلی است که توسط Google تأیید شده است.
هنگامی که نشانههای شناسه در دسترس هستند، میتوانید از آنها برای احراز هویت ایمن با باطن برنامهتان یا ثبت نام خودکار کاربر برای یک حساب جدید بدون نیاز به تأیید آدرس ایمیل کاربر استفاده کنید.
برای ورود به سیستم یا ثبت نام کاربری با یک رمز شناسه، رمز را به باطن برنامه خود ارسال کنید. در باطن، توکن را با استفاده از یک کتابخانه سرویس گیرنده Google API یا یک کتابخانه JWT همه منظوره تأیید کنید. اگر کاربر قبلاً با این حساب Google وارد برنامه شما نشده است، یک حساب جدید ایجاد کنید.
اگر به صورت اختیاری استفاده از nonce را برای کمک به جلوگیری از حملات مجدد انتخاب کرده اید، از getNonce برای ارسال آن به همراه شناسه توکن به سرور باطن خود استفاده کنید و مقدار مورد انتظار را بررسی کنید. توصیه می کنیم برای بهبود ایمنی و امنیت کاربر، قویاً از Nonce استفاده کنید.
یک رمز شناسه از شی credentials دریافت کنید
پس از بازیابی اعتبار یک کاربر، بررسی کنید که آیا شیء اعتبار دارای یک نشانه شناسه است یا خیر. اگر این کار را کرد، آن را به باطن خود ارسال کنید.
جاوا
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(); if (idToken != null) { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token."); } } 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 when { idToken != null -> { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token.") } else -> { // Shouldn't happen. Log.d(TAG, "No ID token!") } } } catch (e: ApiException) { // ... } } } // ... }
یکپارچگی شناسه رمز را بررسی کنید
پس از دریافت کد ID توسط HTTPS POST، باید یکپارچگی توکن را تأیید کنید.
برای تأیید معتبر بودن توکن، اطمینان حاصل کنید که معیارهای زیر برآورده می شوند:
- رمز شناسه به درستی توسط گوگل امضا شده است. از کلیدهای عمومی Google (در قالب JWK یا PEM موجود است) برای تأیید امضای توکن استفاده کنید. این کلیدها به طور منظم چرخانده می شوند. هدر
Cache-Control
را در پاسخ بررسی کنید تا مشخص کنید چه زمانی باید دوباره آنها را بازیابی کنید. - مقدار
aud
در کد ID برابر با یکی از شناسه های مشتری برنامه شما است. این بررسی برای جلوگیری از استفاده از کدهای شناسه صادر شده برای یک برنامه مخرب برای دسترسی به دادههای مربوط به همان کاربر در سرور پشتیبان برنامه شما ضروری است. - مقدار
iss
در کد شناسه برابر باaccounts.google.com
یاhttps://accounts.google.com
است. - زمان انقضا (
exp
) شناسه توکن سپری نشده است. - اگر باید تأیید کنید که رمز شناسه یک حساب سازمانی Google Workspace یا Cloud را نشان میدهد، میتوانید ادعای
hd
را بررسی کنید، که دامنه میزبانی کاربر را نشان میدهد. این باید زمانی استفاده شود که دسترسی به یک منبع را فقط به اعضای دامنه های خاص محدود می کند. عدم وجود این ادعا نشان می دهد که این حساب متعلق به دامنه میزبان گوگل نیست.
با استفاده از فیلدهای email
، email_verified
و hd
، میتوانید تعیین کنید که آیا Google میزبان آدرس ایمیل است یا خیر. در مواردی که Google معتبر است، کاربر به عنوان مالک قانونی حساب شناخته میشود و ممکن است از رمز عبور یا سایر روشهای چالش صرفنظر کنید.
مواردی که گوگل معتبر است:
-
email
دارای پسوند@gmail.com
است، این یک حساب کاربری جیمیل است. -
email_verified
درست است وhd
تنظیم شده است، این یک حساب G Suite است.
کاربران می توانند بدون استفاده از Gmail یا G Suite برای حساب های Google ثبت نام کنند. وقتی email
حاوی پسوند @gmail.com
نیست و hd
وجود ندارد، گوگل معتبر نیست و رمز عبور یا روشهای چالش دیگری برای تأیید کاربر توصیه میشود. email_verified
همچنین می تواند درست باشد زیرا Google در ابتدا کاربر را هنگام ایجاد حساب Google تأیید کرد، اما مالکیت حساب ایمیل شخص ثالث ممکن است از آن زمان تغییر کرده باشد.
به جای نوشتن کد خود برای انجام این مراحل تأیید، ما قویاً توصیه میکنیم از کتابخانه سرویس گیرنده Google API برای پلتفرم خود یا یک کتابخانه JWT همه منظوره استفاده کنید. برای توسعه و اشکالزدایی، میتوانید با نقطه پایانی اعتبارسنجی tokeninfo
ما تماس بگیرید.
استفاده از Google API Client Library
استفاده از یکی از کتابخانه های Google API Client (به عنوان مثال جاوا ، Node.js ، PHP ، Python ) روش توصیه شده برای اعتبارسنجی توکن های Google ID در یک محیط تولید است.
برای تأیید اعتبار یک نشانه شناسه در جاوا، از شی GoogleIdTokenVerifier استفاده کنید. به عنوان مثال:
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; ... GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory) // Specify the CLIENT_ID of the app that accesses the backend: .setAudience(Collections.singletonList(CLIENT_ID)) // Or, if multiple clients access the backend: //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3)) .build(); // (Receive idTokenString by HTTPS POST) GoogleIdToken idToken = verifier.verify(idTokenString); if (idToken != null) { Payload payload = idToken.getPayload(); // Print user identifier String userId = payload.getSubject(); System.out.println("User ID: " + userId); // Get profile information from payload String email = payload.getEmail(); boolean emailVerified = Boolean.valueOf(payload.getEmailVerified()); String name = (String) payload.get("name"); String pictureUrl = (String) payload.get("picture"); String locale = (String) payload.get("locale"); String familyName = (String) payload.get("family_name"); String givenName = (String) payload.get("given_name"); // Use or store profile information // ... } else { System.out.println("Invalid ID token."); }
متد GoogleIdTokenVerifier.verify()
امضای JWT، ادعای aud
، ادعای iss
و ادعای exp
را تأیید میکند.
اگر باید تأیید کنید که رمز شناسه یک حساب سازمانی Google Workspace یا Cloud را نشان میدهد، میتوانید با بررسی نام دامنه بازگردانده شده با روش Payload.getHostedDomain()
ادعای hd
را تأیید کنید. دامنه ادعای email
برای اطمینان از مدیریت حساب توسط یک دامنه یا سازمان کافی نیست.
برای تأیید اعتبار یک نشانه شناسه در Node.js، از کتابخانه Google Auth برای Node.js استفاده کنید. کتابخانه را نصب کنید:
npm install google-auth-library --save
verifyIdToken()
فراخوانی کنید. به عنوان مثال:const {OAuth2Client} = require('google-auth-library'); const client = new OAuth2Client(); async function verify() { const ticket = await client.verifyIdToken({ idToken: token, audience: CLIENT_ID, // Specify the CLIENT_ID of the app that accesses the backend // Or, if multiple clients access the backend: //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3] }); const payload = ticket.getPayload(); const userid = payload['sub']; // If the request specified a Google Workspace domain: // const domain = payload['hd']; } verify().catch(console.error);
تابع verifyIdToken
امضای JWT، ادعای aud
، ادعای exp
و ادعای iss
را تأیید می کند.
اگر باید تأیید کنید که رمز شناسه یک حساب سازمانی Google Workspace یا Cloud را نشان میدهد، میتوانید ادعای hd
را بررسی کنید، که دامنه میزبانی کاربر را نشان میدهد. این باید زمانی استفاده شود که دسترسی به یک منبع را فقط به اعضای دامنه های خاص محدود می کند. عدم وجود این ادعا نشان می دهد که این حساب متعلق به دامنه میزبان گوگل نیست.
برای تأیید اعتبار یک نشانه شناسه در PHP، از Google API Client Library برای PHP استفاده کنید. کتابخانه را نصب کنید (مثلاً با استفاده از Composer):
composer require google/apiclient
verifyIdToken()
فراخوانی کنید. به عنوان مثال:require_once 'vendor/autoload.php'; // Get $id_token via HTTPS POST. $client = new Google_Client(['client_id' => $CLIENT_ID]); // Specify the CLIENT_ID of the app that accesses the backend $payload = $client->verifyIdToken($id_token); if ($payload) { $userid = $payload['sub']; // If the request specified a Google Workspace domain //$domain = $payload['hd']; } else { // Invalid ID token }
تابع verifyIdToken
امضای JWT، ادعای aud
، ادعای exp
و ادعای iss
را تأیید می کند.
اگر باید تأیید کنید که رمز شناسه یک حساب سازمانی Google Workspace یا Cloud را نشان میدهد، میتوانید ادعای hd
را بررسی کنید، که دامنه میزبانی کاربر را نشان میدهد. این باید زمانی استفاده شود که دسترسی به یک منبع را فقط به اعضای دامنه های خاص محدود می کند. عدم وجود این ادعا نشان می دهد که این حساب متعلق به دامنه میزبان گوگل نیست.
برای تأیید اعتبار یک نشانه ID در پایتون، از تابع verify_oauth2_token استفاده کنید. به عنوان مثال:
from google.oauth2 import id_token from google.auth.transport import requests # (Receive token by HTTPS POST) # ... try: # Specify the CLIENT_ID of the app that accesses the backend: idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID) # Or, if multiple clients access the backend server: # idinfo = id_token.verify_oauth2_token(token, requests.Request()) # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]: # raise ValueError('Could not verify audience.') # If the request specified a Google Workspace domain # if idinfo['hd'] != DOMAIN_NAME: # raise ValueError('Wrong domain name.') # ID token is valid. Get the user's Google Account ID from the decoded token. userid = idinfo['sub'] except ValueError: # Invalid token pass
تابع verify_oauth2_token
امضای JWT، ادعای aud
و ادعای exp
را تأیید می کند. همچنین باید ادعای hd
(در صورت وجود) را با بررسی شیئی که verify_oauth2_token
برمی گرداند تأیید کنید. اگر چندین مشتری به سرور باطن دسترسی دارند، ادعای aud
را نیز به صورت دستی تأیید کنید.
تماس با نقطه پایانی tokeninfo
یک راه آسان برای تأیید اعتبار امضای رمز شناسه برای اشکالزدایی ، استفاده از نقطه پایانی tokeninfo
است. فراخوانی این نقطه پایانی شامل یک درخواست شبکه اضافی است که بیشتر اعتبارسنجی را برای شما انجام می دهد، در حالی که شما اعتبارسنجی مناسب و استخراج محموله را در کد خود آزمایش می کنید. برای استفاده در کد تولید مناسب نیست زیرا ممکن است درخواستها کاهش یابد یا در معرض خطاهای متناوب قرار گیرند.
برای تأیید اعتبار یک نشانه شناسه با استفاده از نقطه پایانی tokeninfo
، یک درخواست HTTPS POST یا GET به نقطه پایانی ارسال کنید و رمز ID خود را در پارامتر id_token
ارسال کنید. به عنوان مثال، برای تأیید اعتبار رمز XYZ123، درخواست GET زیر را انجام دهید:
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
اگر توکن به درستی امضا شده باشد و ادعاهای iss
و exp
مقادیر مورد انتظار را داشته باشند، یک پاسخ HTTP 200 دریافت خواهید کرد که در آن بدنه شامل ادعاهای رمز ID با فرمت JSON است. در اینجا یک نمونه پاسخ آمده است:
{ // These six fields are included in all Google ID Tokens. "iss": "https://accounts.google.com", "sub": "110169484474386276334", "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "iat": "1433978353", "exp": "1433981953", // These seven fields are only included when the user has granted the "profile" and // "email" OAuth scopes to the application. "email": "testuser@gmail.com", "email_verified": "true", "name" : "Test User", "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg", "given_name": "Test", "family_name": "User", "locale": "en" }
اگر باید تأیید کنید که رمز ID نشان دهنده یک حساب Google Workspace است، می توانید ادعای hd
را بررسی کنید که دامنه میزبانی کاربر را نشان می دهد. این باید زمانی استفاده شود که دسترسی به یک منبع را فقط به اعضای دامنه های خاص محدود می کند. عدم وجود این ادعا نشان میدهد که این حساب متعلق به دامنه میزبان Google Workspace نیست.
یک حساب کاربری یا جلسه ایجاد کنید
پس از اینکه رمز را تأیید کردید، بررسی کنید که آیا کاربر قبلاً در پایگاه داده کاربر شما قرار دارد یا خیر. اگر چنین است، یک جلسه تأیید اعتبار برای کاربر ایجاد کنید. اگر کاربر هنوز در پایگاه داده کاربر شما نیست، یک رکورد کاربری جدید از اطلاعات موجود در بار توکن شناسه ایجاد کنید و یک جلسه برای کاربر ایجاد کنید. هنگامی که کاربر تازه ایجاد شده را در برنامه خود شناسایی می کنید، می توانید از کاربر درخواست کنید که اطلاعات نمایه اضافی مورد نیاز خود را دریافت کند.
ایمن سازی حساب های کاربران خود با محافظت از حساب های متقابل
وقتی برای ورود کاربر به Google متکی هستید، به طور خودکار از تمام ویژگیهای امنیتی و زیرساختهایی که Google برای محافظت از دادههای کاربر ایجاد کرده است، بهرهمند میشوید. با این حال، در صورت بعید بودن که حساب Google کاربر به خطر بیفتد یا رویداد امنیتی مهم دیگری رخ دهد، برنامه شما نیز میتواند در برابر حمله آسیبپذیر باشد. برای محافظت بهتر از حسابهای خود در برابر هر رویداد امنیتی مهم، از «حفاظت بین حسابها» برای دریافت هشدارهای امنیتی از Google استفاده کنید. وقتی این رویدادها را دریافت میکنید، تغییرات مهمی را در امنیت حساب Google کاربر مشاهده میکنید و سپس میتوانید برای امنیت حسابهای خود در سرویس خود اقدام کنید.