Kết nối OpenID

Bạn có thể sử dụng các API OAuth 2.0 của Google cho cả việc xác thực và uỷ quyền. Tài liệu này mô tả cách triển khai OAuth 2.0 của chúng tôi để xác thực nhằm tuân thủ thông số kỹ thuật OpenID Connect và đã được chứng nhận OpenID. Tài liệu hướng dẫn trong bài viết Sử dụng OAuth 2.0 để truy cập vào các API của Google cũng áp dụng cho dịch vụ này. Nếu muốn khám phá giao thức này theo cách tương tác, bạn nên dùng Playground của Google OAuth 2.0. Để được trợ giúp về Stack Overflow, hãy gắn thẻ câu hỏi của bạn bằng <39;google-oauth#39;.

Thiết lập OAuth 2.0

Trước khi ứng dụng của bạn có thể sử dụng hệ thống xác thực OAuth 2.0 của Google để đăng nhập, bạn phải thiết lập một dự án trong Google API Console để lấy thông tin xác thực OAuth 2.0, đặt URI chuyển hướng và (không bắt buộc) tùy chỉnh thông tin xây dựng thương hiệu mà người dùng thấy trên màn hình đồng ý của người dùng. Bạn cũng có thể sử dụng API Console để tạo tài khoản dịch vụ, bật tính năng thanh toán, thiết lập tính năng lọc và thực hiện các thao tác khác. Để biết thêm thông tin, hãy xem phần Google API Console Trợ giúp.

Nhận thông tin xác thực OAuth 2.0

Bạn cần có thông tin đăng nhập OAuth 2.0, bao gồm mã ứng dụng khách và mật khẩu ứng dụng khách, để xác thực người dùng và truy cập vào các API của Google.

To view the client ID and client secret for a given OAuth 2.0 credential, click the following text: Select credential. In the window that opens, choose your project and the credential you want, then click View.

Or, view your client ID and client secret from the Credentials page in API Console:

  1. Go to the Credentials page.
  2. Click the name of your credential or the pencil () icon. Your client ID and secret are at the top of the page.

Đặt URI chuyển hướng

URI chuyển hướng mà bạn đặt trong API Console sẽ xác định nơi Google gửi phản hồi đến các yêu cầu xác thực của bạn.

To create, view, or edit the redirect URIs for a given OAuth 2.0 credential, do the following:

  1. Go to the Credentials page.
  2. In the OAuth 2.0 client IDs section of the page, click a credential.
  3. View or edit the redirect URIs.

If there is no OAuth 2.0 client IDs section on the Credentials page, then your project has no OAuth credentials. To create one, click Create credentials.

Tùy chỉnh màn hình xin phép người dùng

Đối với người dùng, trải nghiệm xác thực OAuth 2.0 bao gồm màn hình đồng ý mô tả thông tin mà người dùng đang phát hành và các điều khoản áp dụng. Ví dụ: khi người dùng đăng nhập, họ có thể được yêu cầu cấp cho ứng dụng của bạn quyền truy cập vào địa chỉ email và thông tin cơ bản về tài khoản của họ. Bạn yêu cầu quyền truy cập vào thông tin này bằng cách sử dụng tham số scope mà ứng dụng của bạn có trong yêu cầu xác thực. Bạn cũng có thể sử dụng các phạm vi để yêu cầu quyền truy cập vào các API khác của Google.

Màn hình xin phép người dùng cũng trình bày các thông tin về thương hiệu như tên sản phẩm, biểu tượng và URL trang chủ. Bạn kiểm soát thông tin xây dựng thương hiệu trong API Console.

To enable your project's consent screen:

  1. Open the Consent Screen page in the Google API Console.
  2. If prompted, select a project, or create a new one.
  3. Fill out the form and click Save.

Hộp thoại đồng ý sau đây cho biết nội dung mà người dùng sẽ thấy khi kết hợp giữa OAuth 2.0 và phạm vi Google Drive trong yêu cầu. (Hộp thoại chung này được tạo bằng cách sử dụng Google OAuth 2.0 Playground, vì vậy không bao gồm thông tin xây dựng thương hiệu sẽ được đặt trong API Console).

Ảnh chụp màn hình trang lấy sự đồng ý

Truy cập vào dịch vụ

Google và các bên thứ ba cung cấp những thư viện mà bạn có thể sử dụng để chăm sóc nhiều chi tiết triển khai về việc xác thực người dùng và truy cập vào các API của Google. Có thể kể đến một số ví dụ như Dịch vụ nhận dạng của Googlethư viện ứng dụng Google, có sẵn cho nhiều nền tảng.

Nếu bạn chọn không sử dụng thư viện, hãy làm theo hướng dẫn trong phần còn lại của tài liệu này. Hướng dẫn này mô tả quy trình yêu cầu HTTP phụ thuộc vào các thư viện có sẵn.

Xác thực người dùng

Việc xác thực người dùng liên quan đến việc lấy mã thông báo nhận dạng và xác thực mã đó. Mã thông báo ID là một tính năng được chuẩn hoá của OpenID Connect được thiết kế để dùng cho việc chia sẻ xác nhận danh tính trên Internet.

Những phương pháp phổ biến nhất để xác thực người dùng và lấy mã thông báo nhận dạng được gọi là "server" flow và flow "implicit". Luồng máy chủ cho phép máy chủ phụ trợ của một ứng dụng xác minh danh tính của người đó bằng trình duyệt hoặc thiết bị di động. Quy trình ngầm ẩn được dùng khi một ứng dụng phía máy khách (thường là một ứng dụng JavaScript chạy trong trình duyệt) cần truy cập trực tiếp vào API thay vì thông qua máy chủ phụ trợ.

Tài liệu này mô tả cách thực hiện quy trình máy chủ để xác thực người dùng. Quy trình ngầm ẩn phức tạp hơn rất nhiều vì có các rủi ro về bảo mật trong quá trình xử lý và sử dụng mã thông báo phía máy khách. Nếu cần triển khai quy trình ngầm ẩn, bạn rất nên sử dụng Dịch vụ nhận dạng của Google.

Luồng máy chủ

Hãy thiết lập ứng dụng trong API Console để cho phép ứng dụng sử dụng các giao thức này và xác thực người dùng. Khi một người dùng tìm cách đăng nhập bằng Google, bạn cần phải:

  1. Tạo mã thông báo trạng thái chống giả mạo
  2. Gửi yêu cầu xác thực đến Google
  3. Xác nhận mã thông báo trạng thái chống giả mạo
  4. Trao đổi code để nhận mã thông báo truy cập và mã thông báo nhận dạng
  5. Lấy thông tin người dùng từ mã thông báo nhận dạng
  6. Xác thực người dùng

1. Tạo mã thông báo trạng thái chống giả mạo

Bạn phải bảo vệ tính bảo mật của người dùng bằng cách ngăn chặn các cuộc tấn công giả mạo yêu cầu. Bước đầu tiên là tạo một mã thông báo phiên duy nhất để lưu giữ trạng thái giữa ứng dụng của bạn và ứng dụng khách của người dùng. Sau đó, bạn sẽ so khớp mã thông báo phiên duy nhất này với phản hồi xác thực do dịch vụ Đăng nhập Google OAuth trả về để xác minh rằng người dùng đang đưa ra yêu cầu và không phải là kẻ tấn công độc hại. Các mã thông báo này thường được gọi là mã thông báo giả mạo yêu cầu trên nhiều trang web (CSRF).

Một lựa chọn tốt cho mã thông báo trạng thái là một chuỗi gồm 30 ký tự được tạo bằng một trình tạo số ngẫu nhiên chất lượng cao. Một ví dụ khác là một hàm băm được tạo bằng cách ký một số biến trạng thái phiên bằng một khoá được giữ bí mật trong phần phụ trợ của bạn.

Mã sau đây minh hoạ cách tạo mã thông báo phiên duy nhất.

PHP

Bạn phải tải thư viện ứng dụng API của Google dành cho PHP xuống để sử dụng mẫu này.

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = bin2hex(random_bytes(128/8));
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
    'CLIENT_ID' => CLIENT_ID,
    'STATE' => $state,
    'APPLICATION_NAME' => APPLICATION_NAME
));

Java

Bạn phải tải thư viện ứng dụng Google API dành cho Java xuống để sử dụng mẫu này.

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
// Read index.html into memory, and set the client ID,
// token state, and application name in the HTML before serving it.
return new Scanner(new File("index.html"), "UTF-8")
    .useDelimiter("\\A").next()
    .replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
    .replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
    .replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
    APPLICATION_NAME);

Python

Bạn phải tải thư viện ứng dụng Google API dành cho Python xuống để sử dụng mẫu này.

# Create a state token to prevent request forgery.
# Store it in the session for later validation.
state = hashlib.sha256(os.urandom(1024)).hexdigest()
session['state'] = state
# Set the client ID, token state, and application name in the HTML while
# serving it.
response = make_response(
    render_template('index.html',
                    CLIENT_ID=CLIENT_ID,
                    STATE=state,
                    APPLICATION_NAME=APPLICATION_NAME))

2. Gửi yêu cầu xác thực tới Google

Bước tiếp theo là tạo yêu cầu HTTPS GET với thông số URI thích hợp. Lưu ý rằng việc sử dụng HTTPS thay vì HTTP trong tất cả các bước của quy trình này; kết nối HTTP sẽ bị từ chối. Bạn nên truy xuất URI cơ sở từ tài liệu Khám phá bằng cách sử dụng giá trị siêu dữ liệu authorization_endpoint. Cuộc thảo luận sau đây giả định URI cơ sở là https://accounts.google.com/o/oauth2/v2/auth.

Đối với yêu cầu cơ bản, hãy chỉ định các thông số sau:

  • client_id mà bạn nhận được từ API Console Credentials page .
  • response_type, trong yêu cầu luồng mã uỷ quyền cơ bản phải là code. (Đọc thêm tại response_type.)
  • scope, trong yêu cầu cơ bản phải là openid email. (Đọc thêm tại scope.)
  • redirect_uri phải là điểm cuối HTTP trên máy chủ của bạn và sẽ nhận được phản hồi từ Google. Giá trị này phải khớp chính xác với một trong các URI chuyển hướng đã được uỷ quyền cho ứng dụng OAuth 2.0 mà bạn đã thiết lập trong API ConsoleCredentials page. Nếu giá trị này không khớp với URI được phép, thì yêu cầu sẽ không thành công kèm theo lỗi redirect_uri_mismatch.
  • state phải bao gồm giá trị của mã thông báo phiên hoạt động duy nhất chống giả mạo, cũng như mọi thông tin khác cần thiết để khôi phục ngữ cảnh khi người dùng quay lại ứng dụng của bạn, ví dụ: URL bắt đầu. (Đọc thêm tại state.)
  • nonce là một giá trị ngẫu nhiên do ứng dụng của bạn tạo để bật tính năng bảo vệ phát lại khi có mặt.
  • login_hint có thể là địa chỉ email của người dùng hoặc chuỗi sub, tương đương với mã Google của người dùng. Nếu bạn không cung cấp login_hint và người dùng đang đăng nhập, thì màn hình đồng ý sẽ đưa ra yêu cầu phê duyệt để phát hành địa chỉ email của người dùng cho ứng dụng của bạn. (Hãy đọc thêm tại login_hint.)
  • Sử dụng tham số hd để tối ưu hoá quy trình OpenID Connect cho người dùng của một miền cụ thể đã liên kết với một tổ chức Google Cloud. (Đọc thêm tại hd.)

Sau đây là ví dụ về một URI xác thực OpenID Connect hoàn chỉnh, có dấu ngắt dòng và khoảng trắng để dễ đọc:

https://accounts.google.com/o/oauth2/v2/auth?
 response_type=code&
 client_id=424911365001.apps.googleusercontent.com&
 scope=openid%20email&
 redirect_uri=https%3A//oauth2.example.com/code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2-login-demo.example.com%2FmyHome&
 login_hint=jsmith@example.com&
 nonce=0394852-3190485-2490358&
 hd=example.com

Người dùng phải đồng ý nếu ứng dụng của bạn yêu cầu bất kỳ thông tin mới nào về họ, hoặc nếu ứng dụng yêu cầu quyền truy cập vào tài khoản mà họ chưa từng phê duyệt.

3. Xác nhận mã thông báo chống giả mạo

Phản hồi được gửi đến redirect_uri mà bạn đã chỉ định trong yêu cầu. Tất cả các phản hồi sẽ được trả về trong chuỗi truy vấn, như minh hoạ dưới đây:

https://oauth2.example.com/code?state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foa2cb.example.com%2FmyHome&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email%20https://www.googleapis.com/auth/userinfo.email

Trên máy chủ, bạn phải xác nhận rằng state nhận được từ Google khớp với mã thông báo phiên mà bạn đã tạo ở Bước 1. Quy trình xác minh khứ hồi này giúp đảm bảo rằng người dùng (chứ không phải tập lệnh độc hại) thực hiện yêu cầu.

Mã sau đây minh hoạ việc xác nhận mã thông báo phiên mà bạn đã tạo ở Bước 1:

PHP

Bạn phải tải thư viện ứng dụng API của Google dành cho PHP xuống để sử dụng mẫu này.

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
  return new Response('Invalid state parameter', 401);
}

Java

Bạn phải tải thư viện ứng dụng Google API dành cho Java xuống để sử dụng mẫu này.

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if (!request.queryParams("state").equals(
    request.session().attribute("state"))) {
  response.status(401);
  return GSON.toJson("Invalid state parameter.");
}

Python

Bạn phải tải thư viện ứng dụng Google API dành cho Python xuống để sử dụng mẫu này.

# Ensure that the request is not a forgery and that the user sending
# this connect request is the expected user.
if request.args.get('state', '') != session['state']:
  response = make_response(json.dumps('Invalid state parameter.'), 401)
  response.headers['Content-Type'] = 'application/json'
  return response

4. Đổi code để lấy mã truy cập và mã nhận dạng

Nội dung phản hồi bao gồm thông số code, mã uỷ quyền một lần mà máy chủ của bạn có thể trao đổi để lấy mã truy cập và mã thông báo. Máy chủ của bạn sẽ thực hiện việc trao đổi này bằng cách gửi một yêu cầu POST HTTPS. Yêu cầu POST được gửi đến điểm cuối mã thông báo mà bạn sẽ truy xuất từ tài liệu Khám phá bằng cách sử dụng giá trị siêu dữ liệu token_endpoint. Cuộc thảo luận sau đây giả định điểm cuối là https://oauth2.googleapis.com/token. Yêu cầu phải bao gồm các thông số sau trong phần thân POST:

Trường
code Mã uỷ quyền được trả về từ yêu cầu ban đầu.
client_id Mã ứng dụng bạn lấy từ API Console Credentials page, như mô tả trong bài viết Lấy thông tin xác thực OAuth 2.0.
client_secret Mật khẩu ứng dụng khách mà bạn lấy từ API Console Credentials page, như mô tả trong bài viết Lấy thông tin xác thực OAuth 2.0.
redirect_uri Một URI chuyển hướng được ủy quyền cho client_id nhất định được chỉ định trong API Console Credentials page, như mô tả trong phần Đặt URI chuyển hướng.
grant_type Trường này phải chứa giá trị authorization_code, , như được xác định trong thông số kỹ thuật OAuth 2.0.

Yêu cầu thực tế có thể có dạng như ví dụ sau:

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

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your-client-id&
client_secret=your-client-secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Phản hồi thành công cho yêu cầu này chứa các trường sau trong một mảng JSON:

Trường
access_token Mã thông báo có thể được gửi tới API Google.
expires_in Thời gian còn lại của mã thông báo truy cập tính bằng giây.
id_token JWT chứa thông tin nhận dạng về người dùng được Google ký kỹ thuật số.
scope Phạm vi truy cập mà access_token cấp được thể hiện là danh sách các chuỗi phân tách bằng dấu cách, phân biệt chữ hoa chữ thường.
token_type Xác định loại mã thông báo được trả về. Tại thời điểm này, trường này luôn có giá trị Bearer.
refresh_token (không bắt buộc)

Trường này chỉ xuất hiện nếu thông số access_type được đặt thành offline trong yêu cầu xác thực. Để biết chi tiết, hãy xem Làm mới mã thông báo.

5. Lấy thông tin người dùng từ mã thông báo nhận dạng

Mã thông báo nhận dạng là một JWT (Mã thông báo web JSON), là một đối tượng JSON được mã hoá bằng Base64 và được mã hoá. Thông thường, bạn phải xác thực mã thông báo nhận dạng trước khi sử dụng. Tuy nhiên, vì bạn đang giao tiếp trực tiếp với Google qua kênh HTTPS miễn phí trung gian và sử dụng mật khẩu ứng dụng của bạn để xác thực chính bạn với Google, nên bạn có thể yên tâm rằng mã thông báo bạn nhận được thực sự đến từ Google và hợp lệ. Nếu máy chủ chuyển mã thông báo mã nhận dạng đến các thành phần khác của ứng dụng, thì các thành phần khác phải xác thực mã thông báo trước khi sử dụng.

Vì hầu hết các thư viện API đều kết hợp việc xác thực với công việc giải mã các giá trị được mã hoá base64url và phân tích cú pháp JSON trong đó, nên có thể bạn sẽ xác thực được mã thông báo dù sao bạn cũng truy cập được các thông báo xác nhận quyền sở hữu trong mã thông báo mã đó.

Trọng tải mã thông báo mã

Mã thông báo mã nhận dạng là một đối tượng JSON chứa một tập hợp các cặp tên/giá trị. Dưới đây là ví dụ, được định dạng để dễ đọc:

{
  "iss": "https://accounts.google.com",
  "azp": "1234987819200.apps.googleusercontent.com",
  "aud": "1234987819200.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
  "hd": "example.com",
  "email": "jsmith@example.com",
  "email_verified": "true",
  "iat": 1353601026,
  "exp": 1353604926,
  "nonce": "0394852-3190485-2490358"
}

Mã thông báo của Google ID có thể chứa các trường sau (được gọi là thông báo xác nhận quyền sở hữu):

Xác nhận Đã cung cấp Mô tả
aud mọi lúc Đối tượng mà mã thông báo mã này dành cho. Mã này phải là một trong các mã ứng dụng khách OAuth 2.0 của ứng dụng.
exp mọi lúc Thời điểm hết hạn vào hoặc sau thời điểm đó bạn không được chấp nhận mã thông báo nhận dạng. Được biểu thị bằng thời gian Unix (giây số nguyên).
iat mọi lúc Thời gian mã thông báo nhận dạng được phát hành. Được biểu thị bằng giờ Unix (giây số nguyên).
iss mọi lúc Giá trị nhận dạng của nhà phát hành phản hồi. Luôn luôn https://accounts.google.com hoặc accounts.google.com cho mã thông báo của Google ID.
sub mọi lúc Giá trị nhận dạng cho người dùng, duy nhất trong tất cả Tài khoản Google và không bao giờ bị sử dụng lại. Một Tài khoản Google có thể có nhiều địa chỉ email tại những thời điểm khác nhau, nhưng giá trị sub không bao giờ thay đổi. Hãy dùng sub trong ứng dụng của bạn làm khoá nhận dạng duy nhất cho người dùng. Độ dài tối đa là 255 ký tự ASCII phân biệt chữ hoa chữ thường.
at_hash Hàm băm mã thông báo truy cập. Cung cấp thông tin xác thực rằng mã thông báo truy cập được gắn với mã thông báo nhận dạng. Nếu mã thông báo mã nhận dạng được cấp với giá trị access_token trong quy trình máy chủ, thì thông báo xác nhận quyền sở hữu này luôn được đưa vào. Tuyên bố này có thể được dùng làm cơ chế thay thế để bảo vệ khỏi các cuộc tấn công giả mạo yêu cầu trên nhiều trang web. Tuy nhiên, nếu làm theo Bước 1Bước 3, bạn không cần phải xác minh mã truy cập.
azp client_id của người trình bày được uỷ quyền. Yêu cầu xác nhận quyền sở hữu này chỉ cần thiết khi bên yêu cầu mã thông báo mã nhận dạng không phải là đối tượng của mã thông báo mã nhận dạng. Trong trường hợp này, ứng dụng kết hợp của Google có thể sẽ gặp trường hợp ứng dụng web và ứng dụng Android có client_id OAuth 2.0 khác nhưng dùng chung một dự án API của Google.
email Địa chỉ email của người dùng. Giá trị này có thể không phải là duy nhất và không phù hợp để sử dụng làm khoá chính. Chỉ được cung cấp nếu phạm vi của bạn bao gồm giá trị phạm vi email.
email_verified Đúng nếu địa chỉ email của người dùng đã được xác minh; nếu không thì sai.
family_name Họ hoặc (các) họ của người dùng. Có thể được cung cấp khi đưa ra thông báo xác nhận quyền sở hữu name.
given_name Tên hoặc (các) tên của người dùng. Có thể được cung cấp khi đưa ra thông báo xác nhận quyền sở hữu name.
hd Miền liên kết với tổ chức Google Cloud của người dùng. Chỉ được cung cấp nếu người dùng thuộc một tổ chức Google Cloud.
locale Ngôn ngữ của người dùng, được biểu thị bằng thẻ ngôn ngữ BCP 47. Có thể được cung cấp khi đưa ra thông báo xác nhận quyền sở hữu name.
name Tên đầy đủ của người dùng, dưới dạng có thể hiển thị. Có thể được cung cấp khi:
  • Phạm vi yêu cầu bao gồm chuỗi "profile"
  • Mã thông báo nhận dạng được trả về khi làm mới mã thông báo

Khi có name thông báo xác nhận quyền sở hữu, bạn có thể dùng các thông báo đó để cập nhật hồ sơ người dùng của ứng dụng. Xin lưu ý rằng thông báo xác nhận quyền sở hữu này không bao giờ có hiệu lực.

nonce Giá trị của nonce do ứng dụng của bạn cung cấp trong yêu cầu xác thực. Bạn nên thực thi biện pháp bảo vệ chống lại các cuộc tấn công phát lại bằng cách đảm bảo tính năng này chỉ được hiển thị một lần.
picture URL ảnh hồ sơ của người dùng. Có thể được cung cấp khi:
  • Phạm vi yêu cầu bao gồm chuỗi "profile"
  • Mã thông báo nhận dạng được trả về khi làm mới mã thông báo

Khi có picture thông báo xác nhận quyền sở hữu, bạn có thể dùng các thông báo đó để cập nhật hồ sơ người dùng của ứng dụng. Xin lưu ý rằng thông báo xác nhận quyền sở hữu này không bao giờ có hiệu lực.

profile URL của trang hồ sơ người dùng. Có thể được cung cấp khi:
  • Phạm vi yêu cầu bao gồm chuỗi "profile"
  • Mã thông báo nhận dạng được trả về khi làm mới mã thông báo

Khi có profile thông báo xác nhận quyền sở hữu, bạn có thể dùng các thông báo đó để cập nhật hồ sơ người dùng của ứng dụng. Xin lưu ý rằng thông báo xác nhận quyền sở hữu này không bao giờ có hiệu lực.

6. Xác thực người dùng

Sau khi nhận được thông tin người dùng từ mã thông báo nhận dạng, bạn nên truy vấn cơ sở dữ liệu người dùng của ứng dụng. Nếu người dùng đã có trong cơ sở dữ liệu của bạn, bạn nên bắt đầu một phiên ứng dụng cho người dùng đó nếu tất cả yêu cầu đăng nhập được đáp ứng bằng phản hồi API của Google.

Nếu người dùng không tồn tại trong cơ sở dữ liệu người dùng của bạn, bạn nên chuyển hướng người dùng đến quy trình đăng ký người dùng mới. Bạn có thể tự động đăng ký cho người dùng dựa trên thông tin bạn nhận được từ Google hoặc ít nhất bạn cũng có thể điền trước nhiều trường mà bạn yêu cầu trong biểu mẫu đăng ký. Ngoài thông tin trong mã thông báo mã nhận dạng, bạn có thể nhận thêm thông tin về hồ sơ người dùng tại các điểm cuối hồ sơ người dùng của chúng tôi.

Chủ đề nâng cao

Phần sau đây sẽ mô tả chi tiết hơn về API Google OAuth 2.0. Thông tin này dành cho các nhà phát triển có yêu cầu nâng cao về xác thực và uỷ quyền.

Truy cập vào các API khác của Google

Một trong những ưu điểm của việc sử dụng OAuth 2.0 để xác thực là ứng dụng của bạn có thể nhận quyền sử dụng các API khác của Google thay cho người dùng (chẳng hạn như YouTube, Google Drive, Lịch hoặc Danh bạ) cùng lúc với việc xác thực người dùng. Để làm việc này, hãy đưa các phạm vi khác mà bạn cần vào yêu cầu xác thực mà bạn gửi cho Google. Ví dụ: Để thêm nhóm tuổi của người dùng vào yêu cầu xác thực, hãy truyền một tham số phạm vi là openid email https://www.googleapis.com/auth/profile.agerange.read. Người dùng được nhắc thích hợp trên màn hình đồng ý. Mã truy cập mà bạn nhận được từ Google sẽ cho phép bạn truy cập vào tất cả những API liên quan đến các phạm vi truy cập mà bạn đã yêu cầu và đã được cấp.

Làm mới mã thông báo

Trong yêu cầu quyền truy cập API, bạn có thể yêu cầu trả lại mã thông báo làm mới trong quá trình trao đổi code. Mã làm mới cung cấp cho ứng dụng của bạn quyền truy cập liên tục vào các API của Google trong khi người dùng không có mặt trong ứng dụng của bạn. Để yêu cầu mã làm mới, hãy thêm tham số access_type vào offline trong yêu cầu xác thực của bạn.

Những điều cần lưu ý:

  • Hãy nhớ lưu trữ mã làm mới một cách an toàn và vĩnh viễn vì bạn chỉ có thể lấy mã làm mới vào lần đầu tiên thực hiện quy trình trao đổi mã.
  • Có giới hạn về số lượng mã thông báo làm mới được phát hành: một giới hạn cho mỗi tổ hợp khách hàng/người dùng và một giới hạn khác cho mỗi người dùng trên tất cả khách hàng. Nếu ứng dụng của bạn yêu cầu quá nhiều mã làm mới, thì ứng dụng có thể gặp những giới hạn này. Trong trường hợp đó, các mã thông báo làm mới cũ sẽ ngừng hoạt động.

Để biết thêm thông tin, hãy xem bài viết Làm mới mã thông báo truy cập (truy cập ngoại tuyến).

Bạn có thể nhắc người dùng uỷ quyền lại ứng dụng bằng cách đặt thông số prompt thành consent trong yêu cầu xác thực. Khi prompt=consent được đưa vào, màn hình xin phép sẽ hiển thị mỗi khi ứng dụng của bạn yêu cầu cấp quyền cho phạm vi truy cập, ngay cả khi trước đó tất cả phạm vi đã được cấp cho dự án API của Google. Vì lý do này, bạn chỉ nên dùng prompt=consent khi cần thiết.

Để biết thêm thông số về prompt, hãy xem prompt trong bảng Thông số URI xác thực.

Thông số URI xác thực

Bảng sau đây mô tả đầy đủ hơn về các thông số mà API xác thực OAuth 2.0 của Google chấp nhận.

Thông số Bắt buộc Mô tả
client_id (Bắt buộc) Chuỗi mã ứng dụng mà bạn lấy từ Credentials page API Console, như mô tả trong Lấy thông tin đăng nhập OAuth 2.0.
nonce (Bắt buộc) Một giá trị ngẫu nhiên do ứng dụng của bạn tạo ra để bật tính năng bảo vệ phát lại.
response_type (Bắt buộc) Nếu giá trị là code, hãy khởi chạy một Quy trình mã uỷ quyền cơ bản, yêu cầu phải có POST đến điểm cuối mã thông báo để lấy mã thông báo. Nếu giá trị là token id_token hoặc id_token token, hãy chạy một Quy trình ngầm ẩn, yêu cầu sử dụng JavaScript tại URI chuyển hướng để truy xuất mã thông báo từ giá trị nhận dạng #fragment URI.
redirect_uri (Bắt buộc) Xác định nơi phản hồi được gửi. Giá trị của tham số này phải khớp chính xác với một trong các giá trị chuyển hướng đã được uỷ quyền mà bạn đặt trong lược đồ API Console Credentials page (bao gồm lược đồ HTTP hoặc HTTPS, dấu gạch ngang và dấu # "/39;/\39; nếu có).
scope (Bắt buộc)

Thông số phạm vi phải bắt đầu bằng giá trị openid, sau đó bao gồm giá trị profile, giá trị email hoặc cả hai.

Nếu giá trị phạm vi profile xuất hiện, mã thông báo mã nhận dạng có thể (nhưng không được đảm bảo) bao gồm các thông báo xác nhận quyền sở hữu profile mặc định của người dùng.

Nếu giá trị phạm vi email xuất hiện, mã thông báo mã nhận dạng sẽ bao gồm các thông báo xác nhận quyền sở hữu emailemail_verified.

Ngoài các phạm vi dành riêng cho OpenID này, đối số phạm vi của bạn cũng có thể bao gồm các giá trị phạm vi khác. Tất cả các giá trị phạm vi phải được phân tách bằng dấu cách. Ví dụ: nếu bạn muốn quyền truy cập vào từng tệp vào Google Drive của người dùng, thông số phạm vi của bạn có thể là openid profile email https://www.googleapis.com/auth/drive.file.

Để biết thông tin về các phạm vi hiện có, hãy xem Phạm vi OAuth 2.0 cho API Google hoặc tài liệu về API Google mà bạn muốn sử dụng.

state (Không bắt buộc, nhưng bạn nên thực hiện)

Một chuỗi mờ trong suốt trong giao thức; nghĩa là chuỗi này được trả về dưới dạng một thông số URI trong Luồng cơ bản và trong giá trị nhận dạng #fragment của URI trong Luồng ngầm ẩn.

state có thể hữu ích cho các yêu cầu và phản hồi tương ứng. Vì bạn có thể đoán redirect_uri của mình nên việc sử dụng giá trị state có thể giúp đảm bảo rằng kết nối đến là kết quả của yêu cầu xác thực do ứng dụng của bạn khởi tạo. Nếu bạn tạo một chuỗi ngẫu nhiên hoặc mã hoá dữ liệu băm của một số trạng thái máy khách (ví dụ: cookie) trong biến state này, thì bạn có thể xác thực phản hồi để đảm bảo rằng yêu cầu và phản hồi bắt nguồn từ cùng một trình duyệt. Cơ chế này giúp bảo vệ khỏi các cuộc tấn công, chẳng hạn như hành vi giả mạo yêu cầu trên nhiều trang web.

access_type (Không bắt buộc) Các giá trị hợp lệ là offlineonline. Tác động này được ghi lại trong Truy cập ngoại tuyến. Nếu có người yêu cầu mã truy cập, ứng dụng sẽ không nhận được mã làm mới trừ khi bạn chỉ định giá trị offline.
display (Không bắt buộc) Một giá trị chuỗi ASCII để chỉ định cách máy chủ uỷ quyền hiển thị các trang giao diện người dùng xác thực và đồng ý. Các giá trị sau đây được chỉ định và chấp nhận bởi các máy chủ của Google, nhưng không ảnh hưởng đến hành vi của giá trị: page, popup, touchwap.
hd (Không bắt buộc)

Đơn giản hoá quy trình đăng nhập cho các tài khoản do tổ chức Google Cloud sở hữu. Bằng cách thêm miền của tổ chức Google Cloud (ví dụ: mycollege.edu), bạn có thể cho biết rằng giao diện người dùng của tài khoản sẽ được tối ưu hoá cho các tài khoản ở miền đó. Để tối ưu hoá cho tài khoản tổ chức Google Cloud nói chung, thay vì chỉ một miền tổ chức Google Cloud, hãy đặt giá trị của dấu hoa thị (*): hd=*.

Đừng dựa vào tính năng tối ưu hóa giao diện người dùng này để kiểm soát ai có thể truy cập vào ứng dụng của bạn, vì họ có thể sửa đổi các yêu cầu phía máy khách. Hãy đảm bảo bạn xác thực rằng mã thông báo mã nhận dạng trả về có giá trị xác nhận quyền sở hữu hd khớp với giá trị bạn mong đợi (ví dụ: mycolledge.edu). Không giống như thông số yêu cầu, thông báo xác nhận quyền sở hữu bằng mã nhận dạng hd nằm trong mã thông báo bảo mật của Google nên bạn có thể tin tưởng giá trị này.

include_granted_scopes (Không bắt buộc) Nếu thông số này được cung cấp với giá trị true và yêu cầu cấp quyền được cấp, thì lệnh ủy quyền này sẽ bao gồm mọi lệnh ủy quyền trước đây được cấp cho tổ hợp người dùng/ứng dụng này đối với các phạm vi khác; hãy xem phần Ủy quyền gia tăng.

Lưu ý rằng bạn không thể thực hiện ủy quyền gia tăng với luồng Ứng dụng đã cài đặt.

login_hint (Không bắt buộc) Khi biết được người dùng đang cố gắng xác thực, ứng dụng nào có thể cung cấp thông số này dưới dạng gợi ý cho máy chủ xác thực. Việc chuyển gợi ý này sẽ chặn trình chọn tài khoản và điền sẵn hộp email trên biểu mẫu đăng nhập hoặc chọn phiên thích hợp (nếu người dùng đang sử dụng tính năng đăng nhập nhiều tài khoản), điều này có thể giúp bạn tránh được vấn đề xảy ra nếu ứng dụng của bạn đăng nhập không chính xác tài khoản người dùng. Giá trị có thể là một địa chỉ email hoặc chuỗi sub, tương đương với mã nhận dạng Google của người dùng.
prompt (Không bắt buộc) Danh sách các giá trị chuỗi được phân tách bằng dấu cách chỉ định xem máy chủ ủy quyền có nhắc người dùng xác thực lại và đồng ý hay không. Các giá trị có thể sử dụng là:
  • none

    Máy chủ uỷ quyền không hiển thị màn hình xác thực hay đồng ý của người dùng; máy chủ này sẽ trả về lỗi nếu người dùng chưa được xác thực và chưa định cấu hình sẵn sự đồng ý của người dùng cho các phạm vi đã yêu cầu. Bạn có thể sử dụng none để kiểm tra xem ứng dụng có hiện diện xác thực và/hoặc lấy sự đồng ý hay không.

  • consent

    Máy chủ uỷ quyền sẽ nhắc người dùng đồng ý trước khi trả lại thông tin cho máy khách.

  • select_account

    Máy chủ uỷ quyền sẽ nhắc người dùng chọn tài khoản người dùng. Điều này cho phép người dùng có nhiều tài khoản trên máy chủ uỷ quyền có thể chọn trong số nhiều tài khoản mà họ có thể có các phiên hiện tại.

Nếu bạn không chỉ định giá trị nào và người dùng chưa từng cho phép truy cập, thì người dùng sẽ thấy màn hình xin phép.

Xác thực mã thông báo nhận dạng

Bạn cần xác thực tất cả mã thông báo nhận dạng trên máy chủ của mình trừ khi bạn biết rằng mã đó là trực tiếp từ Google. Ví dụ: máy chủ của bạn phải xác minh rằng mã xác thực mã nhận dạng chính xác từ các ứng dụng khách.

Sau đây là những trường hợp phổ biến mà bạn có thể gửi mã thông báo nhận dạng đến máy chủ của mình:

  • Gửi mã thông báo nhận dạng kèm theo các yêu cầu cần được xác thực. Mã thông báo mã nhận dạng cho bạn biết người dùng cụ thể đã gửi yêu cầu cho khách hàng nào và mã thông báo mã nhận dạng nào được cấp.

Mã thông báo mã nhận dạng nhạy cảm và có thể bị sử dụng sai mục đích nếu bị chặn. Bạn phải đảm bảo rằng các mã thông báo này được xử lý một cách an toàn bằng cách chỉ truyền mã thông qua HTTPS và chỉ thông qua dữ liệu POST hoặc trong tiêu đề của yêu cầu. Nếu lưu trữ mã thông báo mã nhận dạng trên máy chủ, bạn cũng phải lưu trữ các mã đó một cách an toàn.

Một điều giúp mã thông báo mã nhận dạng trở nên hữu ích là bạn có thể chuyển mã qua các thành phần khác nhau của ứng dụng. Các thành phần này có thể sử dụng mã thông báo mã nhận dạng như một cơ chế xác thực gọn nhẹ giúp xác thực ứng dụng và người dùng. Tuy nhiên, trước khi có thể sử dụng thông tin trong mã thông báo mã nhận dạng hoặc dựa vào thông tin đó để xác nhận rằng người dùng đã xác thực, bạn phải xác thực thông tin đó.

Để xác thực mã thông báo nhận dạng, bạn cần thực hiện một số bước:

  1. Xác minh rằng mã thông báo nhận dạng được nhà phát hành ký đúng. Mã thông báo do Google cấp được ký bằng một trong những chứng chỉ có tại URI được chỉ định trong giá trị siêu dữ liệu jwks_uri của tài liệu Khám phá.
  2. Xác minh rằng giá trị của thông báo xác nhận quyền sở hữu iss trong mã thông báo mã nhận dạng là https://accounts.google.com hoặc accounts.google.com.
  3. Xác minh rằng giá trị của thông báo xác nhận quyền sở hữu aud trong mã thông báo mã nhận dạng bằng với mã ứng dụng của bạn.
  4. Xác minh rằng chưa qua thời gian hết hạn (thông báo xác nhận quyền sở hữu exp) của mã thông báo nhận dạng.
  5. Nếu bạn đã chỉ định giá trị hd parameter trong yêu cầu, hãy xác minh rằng mã thông báo mã nhận dạng có hd thông báo xác nhận quyền sở hữu khớp với miền được chấp nhận liên kết với một tổ chức của Google Cloud.

Bước 2 đến 5 chỉ bao gồm những phép so sánh chuỗi và ngày tháng khá đơn giản. Vì vậy, chúng tôi sẽ không trình bày chi tiết các bước này tại đây.

Bước đầu tiên phức tạp hơn và bao gồm bước kiểm tra chữ ký mật mã. Để gỡ lỗi, bạn có thể sử dụng điểm cuối tokeninfo của Google để so sánh với quá trình xử lý cục bộ được triển khai trên máy chủ hoặc thiết bị của bạn. Giả sử giá trị mã thông báo nhận dạng của bạn là XYZ123. Sau đó, bạn sẽ huỷ tham chiếu URI https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123. Nếu chữ ký mã thông báo là hợp lệ, phản hồi sẽ là trọng tải JWT trong biểu mẫu đối tượng JSON được giải mã.

Điểm cuối tokeninfo rất hữu ích khi gỡ lỗi nhưng để phục vụ mục đích sản xuất, hãy truy xuất khoá công khai của Google từ điểm cuối khoá và thực hiện xác thực cục bộ. Bạn nên truy xuất URI khoá từ Tài liệu khám phá bằng cách sử dụng giá trị siêu dữ liệu jwks_uri. Các yêu cầu đến điểm cuối gỡ lỗi có thể bị hạn chế hoặc có thể xảy ra lỗi gián đoạn.

Vì Google chỉ thay đổi khoá công khai của mình không thường xuyên, nên bạn có thể lưu những khoá này vào bộ nhớ đệm bằng lệnh bộ nhớ đệm của phản hồi HTTP. Trong phần lớn các trường hợp, hãy tiến hành xác thực cục bộ hiệu quả hơn so với sử dụng điểm cuối tokeninfo. Việc xác thực này yêu cầu bạn phải truy xuất và phân tích cú pháp các chứng chỉ, đồng thời thực hiện các lệnh gọi mật mã thích hợp để kiểm tra chữ ký. May mắn là có những thư viện được gỡ lỗi tốt bằng nhiều ngôn ngữ để thực hiện việc này (xem jwt.io).

Lấy thông tin hồ sơ người dùng

Để có thêm thông tin hồ sơ về người dùng, bạn có thể sử dụng mã truy cập (mà ứng dụng của bạn nhận được trong quy trình xác thực) và tiêu chuẩn OpenID Connect:

  1. Để tuân thủ OpenID, bạn phải bao gồm các giá trị phạm vi openid profile trong yêu cầu xác thực.

    Nếu muốn thêm địa chỉ email của người dùng, bạn có thể chỉ định thêm giá trị phạm vi email. Để chỉ định cả profileemail, bạn có thể thêm những tham số sau vào URI yêu cầu xác thực:

    scope=openid%20profile%20email
  2. Thêm mã truy cập của bạn vào tiêu đề uỷ quyền rồi gửi yêu cầu GET HTTPS đến điểm cuối userinfo. Bạn sẽ truy xuất điểm cuối này từ tài liệu Khám phá bằng giá trị siêu dữ liệu userinfo_endpoint. Nội dung phản hồi thông tin người dùng bao gồm thông tin về người dùng, như mô tả trong OpenID Connect Standard Claims và giá trị siêu dữ liệu claims_supported của tài liệu Khám phá. Người dùng hoặc tổ chức của họ có thể chọn cung cấp hoặc giữ lại một số trường nhất định, vì vậy, bạn có thể không nhận được thông tin cho mọi trường trong phạm vi truy cập được phép.

Tài liệu khám phá

Giao thức OpenID Connect yêu cầu sử dụng nhiều điểm cuối để xác thực người dùng và để yêu cầu tài nguyên, bao gồm mã thông báo, thông tin người dùng và khoá công khai.

Để đơn giản hoá quá trình triển khai và tăng tính linh hoạt, OpenID Connect cho phép sử dụng tài liệu " Discovery, " một tài liệu JSON được tìm thấy ở một vị trí nổi tiếng chứa các cặp khoá-giá trị cung cấp thông tin chi tiết về cấu hình của nhà cung cấp Connect Connect, bao gồm các URI của uỷ quyền, mã thông báo, thu hồi, thông tin người dùng và điểm cuối khóa công khai. Bạn có thể truy xuất tài liệu Khám phá cho dịch vụ OpenID Connect của Google từ:

https://accounts.google.com/.well-known/openid-configuration

Để sử dụng các dịch vụ OpenID Connect của Google, bạn nên mã hóa cứng URI tài liệu khám phá (https://accounts.google.com/.well-known/openid-configuration) vào ứng dụng của mình. Ứng dụng của bạn tìm nạp tài liệu, áp dụng các quy tắc lưu vào bộ nhớ đệm trong phản hồi, sau đó truy xuất các URI điểm cuối từ đó nếu cần. Ví dụ: để xác thực người dùng, mã của bạn sẽ truy xuất giá trị siêu dữ liệu authorization_endpoint (https://accounts.google.com/o/oauth2/v2/auth trong ví dụ bên dưới) làm URI cơ sở cho các yêu cầu xác thực được gửi đến Google.

Sau đây là ví dụ về một tài liệu như vậy; tên trường là những tên được chỉ định trong OpenID Connect Discovery 1.0 (tham khảo tài liệu đó để biết ý nghĩa của tài liệu). Các giá trị chỉ mang tính chất minh họa và có thể thay đổi, mặc dù các giá trị này được sao chép từ phiên bản gần đây của tài liệu Google Khám phá:

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token",
    "none"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "scopes_supported": [
    "openid",
    "email",
    "profile"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "iss",
    "locale",
    "name",
    "picture",
    "sub"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ]
}

Bạn có thể tránh được thông tin khứ hồi HTTP bằng cách lưu vào bộ nhớ đệm các giá trị trong tài liệu Khám phá. Các tiêu đề bộ nhớ đệm HTTP tiêu chuẩn được sử dụng và phải được tôn trọng.

Thư viện ứng dụng

Các thư viện ứng dụng sau giúp việc triển khai OAuth 2.0 trở nên đơn giản hơn bằng cách tích hợp với các khung phổ biến:

Tuân thủ OpenID Connect

Hệ thống xác thực OAuth 2.0 của Google hỗ trợ các tính năng bắt buộc của quy cách OpenID Connect Core. Mọi ứng dụng được thiết kế để hoạt động với OpenID Connect đều phải tương tác với dịch vụ này (ngoại trừ Đối tượng yêu cầu OpenID).