Sunucu tarafında Google Kimlik jetonunu doğrulama

Google bir kimlik jetonu döndürdükten sonra bu jeton, credential parametre adlı bir HTTP POST yöntem isteği tarafından giriş uç noktanıza gönderilir.

Aşağıda, kimlik jetonunu doğrulama ve tüketmeyle ilgili normal adımları gösteren Python dilindeki bir örnek bulunmaktadır:

  1. Siteler Arası İstek Sahtekarlığı (CSRF) jetonunu doğrulayın. Kimlik bilgilerini giriş uç noktanıza gönderdiğinizde, CSRF saldırılarını önlemek için çift çerez gönderme kalıbını kullanırız. Her gönderimden önce bir jeton oluştururuz. Ardından, jeton aşağıdaki kod örneğinde gösterildiği gibi hem çereze hem de posta gövdesine yerleştirilir:

    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. Kimlik jetonunu doğrulayın.

    Jetonun geçerli olduğunu doğrulamak için aşağıdaki ölçütlerin karşılandığından emin olun:

    • Kimlik jetonu Google tarafından gerektiği gibi imzalanmıştır. Jetonun imzasını doğrulamak için Google'ın ortak anahtarlarını (JWK veya PEM biçiminde mevcuttur) kullanın. Bu anahtarlara düzenli olarak rotasyon uygulanır. Bunları tekrar ne zaman almanız gerektiğini belirlemek için yanıttaki Cache-Control üst bilgisini inceleyin.
    • Kimlik jetonundaki aud değeri, uygulamanızın istemci kimliklerinden birine eşit. Bu kontrol, kötü amaçlı bir uygulamaya verilen kimlik jetonlarının, uygulamanızın arka uç sunucusunda aynı kullanıcıyla ilgili verilere erişmek amacıyla kullanılmasını önlemek için gereklidir.
    • Kimlik jetonundaki iss değeri şuna eşit: accounts.google.com veya https://accounts.google.com.
    • Kimlik jetonunun süre sonu (exp) geçmedi.
    • Kimlik jetonunun bir Google Workspace veya Cloud kuruluş hesabını temsil ettiğini doğrulamanız gerekiyorsa kullanıcının barındırılan alanını belirten hd hak talebini kontrol edebilirsiniz. Bu, bir kaynağa erişimi yalnızca belirli alanların üyeleriyle kısıtlarken kullanılmalıdır. Bu iddianın olmaması, hesabın Google tarafından barındırılan bir alana ait olmadığını gösterir.

    Bu doğrulama adımlarını gerçekleştirmek için kendi kodunuzu yazmak yerine platformunuz için bir Google API istemci kitaplığı veya genel amaçlı bir JWT kitaplığı kullanmanızı kesinlikle öneririz. Geliştirme ve hata ayıklama için tokeninfo doğrulama uç noktamızı çağırabilirsiniz.

    Google API İstemci Kitaplığını Kullanma

    Üretim ortamındaki Google kimliği jetonlarını doğrulamak için Google API İstemci Kitaplıklarından birini (ör. Java, Node.js, PHP, Python) kullanmak önerilen yöntemdir.

    Java

    Java'da kimlik jetonunu doğrulamak için GoogleIdTokenVerifier nesnesini kullanın. Örneğin:

    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() yöntemi JWT imzasını, aud hak talebini, iss hak talebini ve exp hak talebini doğrular.

    Kimlik jetonunun bir Google Workspace veya Cloud kuruluş hesabını temsil ettiğini doğrulamanız gerekiyorsa Payload.getHostedDomain() yöntemiyle döndürülen alan adını kontrol ederek hd hak talebini doğrulayabilirsiniz. email talebinin alanı, hesabın bir alan veya kuruluş tarafından yönetildiğinden emin olmak için yeterli değil.

    Node.js

    Node.js'de kimlik jetonunu doğrulamak üzere Node.js için Google Kimlik Doğrulama Kitaplığı'nı kullanın. Kitaplığı yükleyin:

    npm install google-auth-library --save
    Ardından, verifyIdToken() işlevini çağırın. Örneğin:

    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 request specified a G Suite domain:
      // const domain = payload['hd'];
    }
    verify().catch(console.error);
    

    verifyIdToken işlevi, JWT imzasını, aud hak talebini, exp hak talebini ve iss hak talebini doğrular.

    Kimlik jetonunun bir Google Workspace veya Cloud kuruluş hesabını temsil ettiğini doğrulamanız gerekiyorsa kullanıcının barındırılan alanını belirten hd hak talebini kontrol edebilirsiniz. Bu, bir kaynağa erişimi yalnızca belirli alanların üyeleriyle kısıtlarken kullanılmalıdır. Bu iddianın olmaması, hesabın Google tarafından barındırılan bir alana ait olmadığını gösterir.

    PHP

    PHP'de kimlik jetonunu doğrulamak üzere PHP için Google API İstemci Kitaplığı'nı kullanın. Kitaplığı yükleyin (örneğin, Composer kullanarak):

    composer require google/apiclient
    Ardından, verifyIdToken() işlevini çağırın. Örneğin:

    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 request specified a G Suite domain:
      //$domain = $payload['hd'];
    } else {
      // Invalid ID token
    }
    

    verifyIdToken işlevi, JWT imzasını, aud hak talebini, exp hak talebini ve iss hak talebini doğrular.

    Kimlik jetonunun bir Google Workspace veya Cloud kuruluş hesabını temsil ettiğini doğrulamanız gerekiyorsa kullanıcının barındırılan alanını belirten hd hak talebini kontrol edebilirsiniz. Bu, bir kaynağa erişimi yalnızca belirli alanların üyeleriyle kısıtlarken kullanılmalıdır. Bu iddianın olmaması, hesabın Google tarafından barındırılan bir alana ait olmadığını gösterir.

    Python

    Python'da kimlik jetonunu doğrulamak için verify_oauth2_token işlevini kullanın. Örneğin:

    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 auth request is from a G Suite domain:
        # if idinfo['hd'] != GSUITE_DOMAIN_NAME:
        #     raise ValueError('Wrong hosted domain.')
    
        # 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 işlevi, JWT imzasını, aud hak talebini ve exp hak talebini doğrular. Ayrıca, verify_oauth2_token tarafından döndürülen nesneyi inceleyerek hd hak talebini (varsa) doğrulamanız gerekir. Arka uç sunucusuna birden fazla istemci erişirse aud talebini manuel olarak da doğrulayın.

  3. Jetonun geçerliliği onaylandıktan sonra, sitenizin hesap durumunu ilişkilendirmek için Google kimlik jetonundaki bilgileri kullanabilirsiniz:

    • Kayıtlı olmayan kullanıcı: Gerekirse kullanıcının ek profil bilgileri sağlamasına olanak tanıyan bir kaydolan kullanıcı arayüzü (UI) gösterebilirsiniz. Ayrıca, kullanıcının sessizce yeni hesabı ve giriş yapmış bir kullanıcı oturumunu oluşturmasına olanak tanır.

    • Sitenizde zaten mevcut olan bir hesap: Son kullanıcının şifresini girmesine ve eski hesabı Google kimlik bilgilerine bağlamasına olanak tanıyan bir web sayfası gösterebilirsiniz. Bu işlem, kullanıcının mevcut hesaba erişimi olduğunu onaylar.

    • Geri dönen birleşik kullanıcı: Kullanıcının sessizce oturum açmasını sağlayabilirsiniz.