رمز Google ID را در سمت سرور خود تأیید کنید

پس از اینکه Google یک رمز شناسه را برگرداند، با درخواست روش HTTP POST ، با credential نام پارامتر، به نقطه پایانی ورود به سیستم شما ارسال می‌شود.

مثال زیر در زبان پایتون است که مراحل معمول اعتبارسنجی و مصرف نشانه ID را نشان می دهد:

  1. توکن جعل درخواست متقابل (CSRF) را تأیید کنید. هنگامی که اعتبارنامه را به نقطه پایانی ورود خود ارسال می کنید، ما از الگوی دو ارسال کوکی برای جلوگیری از حملات CSRF استفاده می کنیم. قبل از هر ارسال، یک توکن تولید می کنیم. سپس، توکن در داخل کوکی و بدنه پست قرار می گیرد، همانطور که در مثال کد زیر نشان داده شده است:

    csrf_token_cookie = self.request.cookies.get('g_csrf_token')
    if not csrf_token_cookie:
        webapp2.abort(400, 'No CSRF token in Cookie.')
    csrf_token_body = self.request.get('g_csrf_token')
    if not csrf_token_body:
        webapp2.abort(400, 'No CSRF token in post body.')
    if csrf_token_cookie != csrf_token_body:
        webapp2.abort(400, 'Failed to verify double submit cookie.')
    
  2. شناسه رمز را تأیید کنید.

    برای تأیید معتبر بودن توکن، اطمینان حاصل کنید که معیارهای زیر برآورده می شوند:

    • رمز شناسه به درستی توسط گوگل امضا شده است. از کلیدهای عمومی 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

    برای تأیید اعتبار یک نشانه شناسه در 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

    برای تأیید اعتبار یک نشانه شناسه در 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 را نیز به صورت دستی تأیید کنید.

  3. پس از تأیید اعتبار نشانه، می‌توانید از اطلاعات موجود در شناسه Google برای مرتبط کردن وضعیت حساب سایت خود استفاده کنید:

    • کاربر ثبت‌نشده: می‌توانید یک رابط کاربری ثبت‌نام (UI) نشان دهید که به کاربر اجازه می‌دهد در صورت نیاز اطلاعات نمایه اضافی را ارائه دهد. همچنین به کاربر این امکان را می‌دهد که در سکوت یک حساب کاربری جدید و یک جلسه کاربر وارد شده ایجاد کند.

    • یک حساب موجود که از قبل در سایت شما وجود دارد: می توانید صفحه وب را نشان دهید که به کاربر نهایی امکان می دهد رمز عبور خود را وارد کرده و حساب قدیمی را با اعتبار Google خود پیوند دهد. این تأیید می کند که کاربر به حساب موجود دسترسی دارد.

    • کاربر فدرال بازگشتی: می‌توانید در سکوت کاربر را وارد کنید.