Liên kết hợp lý với OAuth và Đăng nhập bằng Google

Tổng quan

Tính năng Liên kết hợp lý để đăng nhập bằng Google OAuth sẽ thêm tính năng Đăng nhập bằng Google ngoài Tính năng liên kết OAuth. Điều này mang lại trải nghiệm liên kết liền mạch cho người dùng Google và cũng cho phép tạo tài khoản, cho phép người dùng tạo tài khoản mới trên dịch vụ của bạn bằng Tài khoản Google của họ.

Để liên kết tài khoản bằng OAuth và tính năng Đăng nhập bằng Google, hãy làm theo những bước chung sau đây:

  1. Trước tiên, hãy yêu cầu người dùng đồng ý truy cập vào hồ sơ trên Google của họ.
  2. Sử dụng thông tin trong hồ sơ của họ để kiểm tra xem tài khoản người dùng có tồn tại hay không.
  3. Đối với người dùng hiện tại, hãy liên kết các tài khoản đó.
  4. Nếu bạn không tìm thấy thông tin khớp cho người dùng Google trong hệ thống xác thực, hãy xác thực mã thông báo nhận dạng mà Google nhận được. Sau đó, bạn có thể tạo người dùng dựa trên thông tin tiểu sử có trong mã thông báo nhận dạng.
Hình này cho thấy các bước để người dùng liên kết Tài khoản Google của họ bằng cách sử dụng quy trình liên kết đơn giản. Ảnh chụp màn hình đầu tiên cho thấy cách người dùng có thể chọn ứng dụng của bạn để liên kết. Ảnh chụp màn hình thứ hai cho phép người dùng xác nhận xem họ đã có tài khoản trên dịch vụ của bạn hay chưa. Ảnh chụp màn hình thứ ba cho phép người dùng chọn Tài khoản Google mà họ muốn liên kết. Ảnh chụp màn hình thứ tư cho thấy thông báo xác nhận liên kết Tài khoản Google với ứng dụng của bạn. Ảnh chụp màn hình thứ năm cho thấy một tài khoản người dùng được liên kết thành công trong ứng dụng Google.

Hình 1 Liên kết tài khoản trên điện thoại của người dùng bằng tính năng Liên kết được đơn giản hóa

Yêu cầu đối với việc liên kết đơn giản

Triển khai máy chủ OAuth của bạn

Điểm cuối token trao đổi phải hỗ trợ các ý định check, create, get. Dưới đây là các bước đã hoàn thành thông qua quy trình liên kết tài khoản và cho biết thời điểm các ý định khác nhau được gọi:

  1. Người dùng có tài khoản trong hệ thống xác thực của bạn không? (Người dùng quyết định bằng cách chọn CÓ hoặc KHÔNG)
    1. CÓ : Người dùng có sử dụng email liên kết với Tài khoản Google của họ để đăng nhập vào nền tảng của bạn không? (Người dùng quyết định bằng cách chọn CÓ hoặc KHÔNG)
      1. CÓ : Người dùng có tài khoản trùng khớp trong hệ thống xác thực của bạn không? (check intent được gọi để xác nhận)
        1. CÓ: get intent sẽ được gọi và tài khoản sẽ được liên kết nếu nhận được ý định trả lại thành công.
        2. KHÔNG : Tạo Tài khoản mới? (Người dùng quyết định bằng cách chọn CÓ hoặc KHÔNG)
          1. CÓ : create intent được gọi và tài khoản sẽ được liên kết nếu quá trình tạo ý định thành công.
          2. KHÔNG : Luồng OAuth trên web được kích hoạt, người dùng được chuyển hướng đến trình duyệt của họ và người dùng được cung cấp tuỳ chọn liên kết với một email khác.
      2. KHÔNG : Luồng OAuth trên web được kích hoạt, người dùng được chuyển hướng đến trình duyệt của họ và người dùng có thể chọn liên kết với một email khác.
    2. KHÔNG : Người dùng có tài khoản trùng khớp trong hệ thống xác thực của bạn không? (check intent được gọi để xác nhận)
      1. CÓ : get intent sẽ được gọi và tài khoản sẽ được liên kết nếu nhận được ý định trả lại thành công.
      2. KHÔNG: create intent được gọi và tài khoản sẽ được liên kết nếu quá trình tạo ý định thành công.

Kiểm tra tài khoản người dùng hiện có (kiểm tra ý định)

Sau khi người dùng đồng ý truy cập hồ sơ trên Google của họ, Google sẽ gửi một yêu cầu chứa xác nhận có chữ ký về danh tính của người dùng Google. Xác nhận chứa thông tin bao gồm ID tài khoản Google, tên và địa chỉ email của người dùng. Điểm cuối trao đổi mã thông báo được định cấu hình cho dự án của bạn xử lý yêu cầu đó.

Nếu tài khoản Google tương ứng đã có mặt trong hệ thống xác thực của bạn, token trä l trao đổi thiết bị đầu cuối của bạn với account_found=true . Nếu tài khoản Google không phù hợp với một người dùng hiện có, thiết bị đầu cuối trao đổi thẻ của bạn trả về một HTTP 404 Not Found lỗi với account_found=false .

Yêu cầu có dạng sau:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=check&assertion=JWT&scope=SCOPES

Điểm cuối trao đổi mã thông báo của bạn phải có thể xử lý các thông số sau:

Thông số điểm cuối mã thông báo
intent Đối với những yêu cầu này, giá trị của tham số này là check .
grant_type Loại mã thông báo được trao đổi. Đối với những yêu cầu này, tham số này có giá trị urn:ietf:params:oauth:grant-type:jwt-bearer .
assertion Mã thông báo web JSON (JWT) cung cấp xác nhận có chữ ký về danh tính của người dùng Google. JWT chứa thông tin bao gồm ID tài khoản Google, tên và địa chỉ email của người dùng.

Để đáp ứng với check yêu cầu ý định, thiết bị đầu cuối trao đổi thẻ của bạn phải thực hiện các bước sau:

  • Xác thực và giải mã khẳng định JWT.
  • Kiểm tra xem tài khoản Google đã có trong hệ thống xác thực của bạn chưa.
Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.

Kiểm tra xem tài khoản Google đã có trong hệ thống xác thực của bạn chưa

Kiểm tra xem một trong các điều kiện sau có đúng không:

  • ID Tài khoản Google, tìm thấy vào những năm khẳng định sub lĩnh vực, là trong cơ sở dữ liệu người dùng của bạn.
  • Địa chỉ email trong xác nhận khớp với một người dùng trong cơ sở dữ liệu người dùng của bạn.

Nếu một trong hai điều kiện là đúng, người dùng đã đăng ký. Trong trường hợp đó, hãy trả lại một phản hồi như sau:

HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8

{
  "account_found":"true",
}

Nếu cả ID tài khoản Google và địa chỉ email được chỉ định trong xác nhận đều khớp với người dùng trong cơ sở dữ liệu của bạn, thì người dùng đó chưa đăng ký. Trong trường hợp này, thiết bị đầu cuối trao đổi thẻ của bạn cần phải trả lời với một lỗi HTTP 404 đó quy định cụ thể "account_found": "false" , như trong ví dụ sau:

HTTP/1.1 404 Not found
Content-Type: application/json;charset=UTF-8

{
  "account_found":"false",
}

Handle automatic linking (get intent)

After the user gives consent to access their Google profile, Google sends a request that contains a signed assertion of the Google user's identity. The assertion contains information that includes the user's Google Account ID, name, and email address. The token exchange endpoint configured for your project handles that request.

If the corresponding Google Account is already present in your authentication system, your token exchange endpoint returns a token for the user. If the Google Account doesn't match an existing user, your token exchange endpoint returns a linking_error error and optional login_hint.

The request has the following form:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=get&assertion=JWT&scope=SCOPES

Your token exchange endpoint must be able to handle the following parameters:

Token endpoint parameters
intent For these requests, the value of this parameter is get.
grant_type The type of token being exchanged. For these requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address.
scope Optional: Any scopes that you've configured Google to request from users.

To respond to the get intent requests, your token exchange endpoint must perform the following steps:

  • Validate and decode the JWT assertion.
  • Check if the Google account is already present in your authentication system.
Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.

Check if the Google account is already present in your authentication system

Check whether either of the following conditions are true:

  • The Google Account ID, found in the assertion's sub field, is in your user database.
  • The email address in the assertion matches a user in your user database.

If an account is found for the user, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

In some cases, account linking based on ID token might fail for the user. If it does so for any reason, your token exchange endpoint needs to reply with a HTTP 401 error that specifies error=linking_error, as the following example shows:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

When Google receives a 401 error response with linking_error, Google sends the user to your authorization endpoint with login_hint as a parameter. The user completes account linking using the OAuth linking flow in their browser.

Handle account creation via Google Sign-In (create intent)

When a user needs to create an account on your service, Google makes a request to your token exchange endpoint that specifies intent=create.

The request has the following form:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&assertion=JWT

Your token exchange endpoint must able to handle the following parameters:

Token endpoint parameters
intent For these requests, the value of this parameter is create.
grant_type The type of token being exchanged. For these requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address.

The JWT within the assertion parameter contains the user's Google Account ID, name, and email address, which you can use to create a new account on your service.

To respond to the create intent requests, your token exchange endpoint must perform the following steps:

  • Validate and decode the JWT assertion.
  • Validate user information and create new account.
Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.

Validate user information and create new account

Check whether either of the following conditions are true:

  • The Google Account ID, found in the assertion's sub field, is in your user database.
  • The email address in the assertion matches a user in your user database.

If either condition is true, prompt the user to link their existing account with their Google Account. To do so, respond to the request with an HTTP 401 error that specifies error=linking_error and gives the user's email address as the login_hint. The following is a sample response:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

When Google receives a 401 error response with linking_error, Google sends the user to your authorization endpoint with login_hint as a parameter. The user completes account linking using the OAuth linking flow in their browser.

If neither condition is true, create a new user account with the information provided in the JWT. New accounts don't typically have a password set. It's recommended that you add Google Sign-In to other platforms to enable users to log in with Google across the surfaces of your application. Alternatively, you can email the user a link that starts your password recovery flow to allow the user to set a password to sign in on other platforms.

When the creation is completed, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

Lấy mã ứng dụng khách API của Google

Bạn sẽ được yêu cầu cung cấp mã nhận dạng ứng dụng khách Google API trong quá trình đăng ký Liên kết tài khoản.

Để nhận mã ứng dụng khách API bằng dự án bạn đã tạo trong khi hoàn thành các bước Liên kết OAuth. Để làm được điều này, vui lòng hoàn thành các bước sau:

  1. Mở trang Thông tin xác thực của Bảng điều khiển API của Google.
  2. Tạo hoặc chọn một dự án API của Google.

    Nếu dự án của bạn không có Mã ứng dụng khách cho loại Ứng dụng web, hãy nhấp vào Tạo thông tin xác thực > Mã ứng dụng OAuth để tạo một mã. Hãy nhớ đưa miền của trang web vào hộp Nguồn gốc JavaScript được cho phép. Khi thực hiện thử nghiệm hoặc phát triển cục bộ, bạn phải thêm cả http://localhosthttp://localhost:<port_number> vào trường Nguồn gốc JavaScript được ủy quyền.

Xác thực quá trình triển khai

You can validate your implementation by using the OAuth 2.0 Playground tool.

In the tool, do the following steps:

  1. Click Configuration to open the OAuth 2.0 Configuration window.
  2. In the OAuth flow field, select Client-side.
  3. In the OAuth Endpoints field, select Custom.
  4. Specify your OAuth 2.0 endpoint and the client ID you assigned to Google in the corresponding fields.
  5. In the Step 1 section, don't select any Google scopes. Instead, leave this field blank or type a scope valid for your server (or an arbitrary string if you don't use OAuth scopes). When you're done, click Authorize APIs.
  6. In the Step 2 and Step 3 sections, go through the OAuth 2.0 flow and verify that each step works as intended.

You can validate your implementation by using the Google Account Linking Demo tool.

In the tool, do the following steps:

  1. Click the Sign-in with Google button.
  2. Choose the account you'd like to link.
  3. Enter the service ID.
  4. Optionally enter one or more scopes that you will request access for.
  5. Click Start Demo.
  6. When prompted, confirm that you may consent and deny the linking request.
  7. Confirm that you are redirected to your platform.