Kết nối OpenID

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

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 để nhận thông tin xác thực OAuth 2.0, đặt URI chuyển hướng và (không bắt buộc) tuỳ chỉnh thông tin thương hiệu mà người dùng thấy trên màn hình về sự đồ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 Trợ giúp Google API Console.

Nhận thông tin đăng nhập OAuth 2.0

Bạn cần có thông tin đăng nhập OAuth 2.0, bao gồm cả mã ứng dụng khách và khóa bí mật của ứng dụng để xác thực người dùng và có quyền 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 xác định nơi Google gửi phản hồi cho yêu cầu xác thực của bạn.

Để tạo, xem hoặc chỉnh sửa các URI chuyển hướng cho thông tin xác thực OAuth 2.0, hãy làm như sau:

  1. Go to the Credentials page.
  2. Trong phần ID khách hàng OAuth 2.0 của trang, nhấp vào thông tin xác thực.
  3. Xem hoặc chỉnh sửa các URI chuyển hướng.

Nếu không có phần ID khách OAuth 2.0 trên trang Thông tin xác thực, thì dự án của bạn không có thông tin xác thực OAuth. Để tạo một, bấm Tạo thông tin đăng nhập .

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

Đối với người dùng của bạn, trải nghiệm xác thực OAuth 2.0 sẽ 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 tài khoản cơ bả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 đưa vào yêu cầu xác thực. Bạn cũng có thể sử dụng 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 hiển thị thông tin thương hiệu, chẳng hạn như tên sản phẩm, biểu trư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.

Để bật màn hình đồng ý của dự án của bạn:

  1. Mở Consent Screen page trong Google API Console .
  2. If prompted, select a project, or create a new one.
  3. Điền vào biểu mẫu và nhấp vào Lưu .

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

Ảnh chụp màn hình trang đồng ý

Truy cập dịch vụ

Google và các bên thứ ba cung cấp các thư viện mà bạn có thể sử dụng để xử lý nhiều chi tiết triển khai trong việc xác thực người dùng và truy cập vào các API của Google. Ví dụ bao gồm 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, trong đó có mô tả các luồng yêu cầu HTTP dưới thư viện hiện có.

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

Việc xác thực người dùng bao gồm việc lấy mã thông báo nhận dạng và xác thực mã đó. Mã nhận dạng là một tính năng tiêu chuẩn của OpenID Connect được thiết kế để sử dụng trong việc chia sẻ các khẳng định danh tính trên Internet.

Các phương pháp phổ biến nhất để xác thực người dùng và nhận mã thông báo nhận dạng được gọi là quy trình "máy chủ" và quy trình "ngầm ẩn". Luồng máy chủ cho phép máy chủ phụ trợ của ứ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. Luồng ngầm ẩn được dùng khi một ứng dụng phía máy khách (thường là ứng dụng JavaScript chạy trong trình duyệt) cần truy cập trực tiếp vào các API thay vì 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 đáng kể do có các rủi ro 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 một quy trình ngầm ẩn, bạn nên sử dụng Dịch vụ nhận dạng của Google.

Luồng máy chủ

Hãy nhớ thiết lập ứng dụng của bạn 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 người dùng cố đăng nhập bằng Google, bạn cần:

  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. Exchange code để lấy mã truy cập và mã thông báo nhận dạng
  5. Nhận 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ệ bảo mật cho người dùng của mình 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 chứa trạng thái giữa ứng dụng của bạn và ứng dụng của người dùng. Sau đó, bạn 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 mà 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 chứ 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 mã thông báo trạng thái phù hợp là một chuỗi gồm khoảng 30 ký tự được tạo bằng trình tạo số ngẫu nhiên chất lượng cao. Một phương thức 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 của bạn với một khóa được giữ bí mật trên phần phụ trợ.

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

1.199

Bạn phải tải thư viện ứng dụng API Google cho PHP để 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 API Google cho Java để 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 API Google cho Python để 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 đến Google

Bước tiếp theo là tạo một yêu cầu HTTPS GET với các tham số URI thích hợp. Lưu ý việc sử dụng HTTPS thay vì HTTP trong tất cả các bước của quá trình này; kết nối HTTP 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 tham 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ã ủy 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 để 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 đã định cấu hình trong API Console Credentials page. Nếu giá trị này không khớp với một URI được uỷ quyền, thì yêu cầu sẽ không thành công với lỗi redirect_uri_mismatch.
  • state phải bao gồm giá trị của mã thông báo phiên 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, 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ó.
  • 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 hiện đã đăng nhập, thì màn hình xin phép sẽ có 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 thêm tại login_hint.)
  • Sử dụng thông số hd để tối ưu hoá quy trình kết nối OpenID cho người dùng của một miền cụ thể liên kết với 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, với cá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 họ cung cấp thông tin mới 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 phê duyệt trước đó.

3. Xác nhận mã thông báo trạng thái 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ả 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. Quá trình xác minh hai chiều này giúp đảm bảo rằng người dùng, chứ không phải một tập lệnh độc hại, đang đưa ra 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:

1.199

Bạn phải tải thư viện ứng dụng API Google cho PHP để 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 API Google cho Java để 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 API Google cho Python để 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. Trao đổi code để lấy mã truy cập và mã nhận dạng

Phản hồi bao gồm tham 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ã nhận dạng. Máy chủ của bạn sẽ thực hiện hoạt động 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 của mã thông báo mà bạn nên 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 có các tham số sau trong phần nội dung POST:

Các trường
code Mã ủy quyền được trả về qua yêu cầu ban đầu.
client_id Mã ứng dụng bạn nhận được từ API Console Credentials page, như mô tả trong Nhận thông tin đăng nhập OAuth 2.0.
client_secret Mật khẩu ứng dụng khách mà bạn nhận được từ API Console Credentials page, như mô tả trong Nhận thông tin đăng nhập OAuth 2.0.
redirect_uri Một URI chuyển hướng được uỷ quyền cho client_id cụ thể đượ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, theo định nghĩa 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

Một 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:

Các trường
access_token Một mã thông báo có thể gửi đến API Google.
expires_in Thời gian tồn tại của mã thông báo truy cập tính bằng giây.
id_token Một JWT chứa thông tin nhận dạng về người dùng đã được Google ký bằng chữ số.
scope Phạm vi truy cập do access_token cấp được biểu thị dưới dạng danh sách các chuỗi được phân tách bằng dấu cách và phân biệt chữ hoa chữ thường.
token_type Xác định loại mã thông báo được trả về. Lúc 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ỉ hiện diện nếu tham 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 ID

Mã thông báo ID là JWT (Mã thông báo web JSON), là một đối tượng JSON được mã hóa Base64 đã ký mã hóa. Thông thường, điều quan trọng là 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 một kênh HTTPS không phải là trung gian và sử dụng khóa bí mật của ứng dụng để xác thực bản thân với Google, nên bạn có thể yên tâm rằng mã mà bạn nhận được thực sự là của Google và hợp lệ. Nếu máy chủ của bạn chuyển mã thông báo cho các thành phần khác của ứng dụng, 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, một điều cực kỳ quan trọng.

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

Tải trọng của mã thông báo ID

Mã thông báo ID là đối tượng JSON chứa một tập hợp các cặp tên/giá trị. Sau đây là một ví dụ có định dạng rõ ràng:

{
  "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 (gọi là thông báo xác nhận quyền sở hữu):

Xác nhận quyền sở hữu Đã cung cấp Mô tả
aud mọi lúc Đối tượng mà mã thông báo này dành cho. Đâ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 gian hết hạn vào hoặc sau ngày mà mã thông báo ID không được chấp nhận. Được biểu thị theo giờ Unix (giây số nguyên).
iat mọi lúc Thời gian cấp mã thông báo. Được biểu thị theo 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 cho phản hồi. Luôn là https://accounts.google.com hoặc accounts.google.com đối với mã thông báo của Google ID.
sub mọi lúc Giá trị nhận dạng của người dùng, là duy nhất trong tất cả Tài khoản Google và không bao giờ được sử dụng lại. Tài khoản Google có thể có nhiều địa chỉ email tại nhiều thời điểm, nhưng giá trị sub thì không bao giờ thay đổi. Sử 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 xác thực rằng mã truy cập được gắn với mã thông báo nhận dạng. Nếu mã thông báo ID được phát hành với giá trị access_token trong luồng máy chủ, thì xác nhận quyền sở hữu này luôn được đưa vào. Thông báo xác nhận quyền sở hữu này có thể được dùng làm cơ chế thay thế để ngăn chặn các cuộc tấn công giả mạo yêu cầu trên nhiều trang web, nhưng nếu bạn làm theo Bước 1Bước 3 thì không cần thiết phải xác minh mã truy cập.
azp client_id của người trình bày được ủy quyền. Thông báo 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 đó không giống với đối tượng có mã thông báo đó. Đây có thể là trường hợp của Google đối với các ứng dụng kết hợp, trong đó ứ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 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 cho người dùng này và không phù hợp để sử dụng làm khóa 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 True nếu địa chỉ e-mail của người dùng đã được xác minh; nếu không thì false.
family_name Họ hoặc tên của người dùng. Có thể được cung cấp khi có thông báo xác nhận quyền sở hữu name.
given_name (Các) tên hoặc tên của người dùng. Có thể được cung cấp khi có 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 một thẻ ngôn ngữ BCP 47. Có thể được cung cấp khi có 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ạ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 "hồ sơ"
  • Mã thông báo nhận dạng được trả về từ lần làm mới mã thông báo

Khi có thông báo xác nhận quyền sở hữu name, bạn có thể sử dụng các thông báo này để cập nhật hồ sơ người dùng của ứng dụng. Xin lưu ý rằng chúng tôi không đảm bảo sẽ đưa ra khiếu nại này.

nonce Giá trị 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 hiện biện pháp bảo vệ trước các cuộc tấn công phát lại bằng cách đảm bảo nội dung chỉ xuất hiện 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 "hồ sơ"
  • Mã thông báo nhận dạng được trả về từ lần làm mới mã thông báo

Khi có thông báo xác nhận quyền sở hữu picture, bạn có thể sử dụng các thông báo này để cập nhật hồ sơ người dùng của ứng dụng. Xin lưu ý rằng chúng tôi không đảm bảo sẽ đưa ra khiếu nại này.

profile URL trang 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 "hồ sơ"
  • Mã thông báo nhận dạng được trả về từ lần làm mới mã thông báo

Khi có thông báo xác nhận quyền sở hữu profile, bạn có thể sử dụng các thông báo này để cập nhật hồ sơ người dùng của ứng dụng. Xin lưu ý rằng chúng tôi không đảm bảo sẽ đưa ra khiếu nại này.

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 ID, 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 đã tồn tại trong cơ sở dữ liệu của bạn, bạn nên bắt đầu phiên ứng dụng cho người dùng đó nếu phản hồi API Google đáp ứng tất cả yêu cầu đăng nhập.

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 luồng đă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 ID, bạn có thể nhận thêm thông tin 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

Các phần sau đây mô tả chi tiết hơn về API Google OAuth 2.0. Thông tin này dành cho nhà phát triển có cá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 lợi thế của việc sử dụng OAuth 2.0 để xác thực là ứng dụng của bạn có thể được phép sử dụng các API khác của Google thay mặt 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. Để thực hiện việc này, hãy thêm những phạm vi khác mà bạn cần trong 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 tham số phạm vi 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 cho phép bạn truy cập tất cả API liên quan đến phạm vi truy cập mà bạn đã yêu cầu và đã được cấp quyền.

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

Trong yêu cầu truy cập API, bạn có thể yêu cầu trả lại mã 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. Để 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ể nhận được mã làm mới vào lần đầu tiên bạn thực hiện quy trình trao đổi mã.
  • Có giới hạn về số lượng mã làm mới được phát hành: một giới hạn cho mỗi kết hợp ứng dụ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ả ứng dụng. Nếu ứng dụng của bạn yêu cầu quá nhiều mã làm mới, ứng dụng có thể bị giới hạn. Trong trường hợp này, mã 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ã truy cập (truy cập ngoại tuyến).

Bạn có thể nhắc người dùng cấp quyền lại cho ứng dụng của bạn 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 lấy sự đồng ý sẽ hiển thị mỗi khi ứng dụng yêu cầu ủy quyền phạm vi truy cập, ngay cả khi tất cả phạm vi đã được cấp trước đó cho dự án API Google của bạn. Vì lý do này, chỉ bao gồm prompt=consent khi cần thiết.

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

Tham số URI xác thực

Bảng sau cung cấp thông tin mô tả đầy đủ hơn về các thông số được 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 khách bạn nhận được từ API Console Credentials page, như được 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 để 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 Luồng mã ủy 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 khởi chạy một luồng 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.
redirect_uri (Bắt buộc) Xác định nơi phản hồi được gửi. Giá trị của thông 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 API Console( Credentials page (bao gồm giao thức HTTP hoặc HTTPS, chữ hoa và chữ số "/", 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 có giá trị phạm vi profile, mã thông báo ID có thể (nhưng không đảm bảo) sẽ 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 có giá trị phạm vi email, mã thông báo 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 cụ thể theo 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ả 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 truy cập trên mỗi tệp vào Google Drive của một người dùng, tham 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ần Pham 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 đục được được thực hiện trọn vòng trong giao thức; có nghĩa là chuỗi được trả về dưới dạng tham số URI trong luồng Cơ bản và trong giá trị nhận dạng URI #fragment 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ì redirect_uri của bạn có thể được đoán, nên việc sử dụng giá trị state có thể giúp đảm bảo rằng một 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 tạo một chuỗi ngẫu nhiên hoặc mã hoá hàm băm của một số trạng thái ứng dụng (ví dụ: cookie) trong biến state này, 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 trong cùng một trình duyệt. Phương thức này giúp bảo vệ tài khoản trước các cuộc tấn công như giả mạo yêu cầu trên nhiều trang web.

access_type (Không bắt buộc) Giá trị được phép là offlineonline. Hiệu ứng này được ghi lại trong Truy cập ngoại tuyến. Nếu đang 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 đồng ý và xác thực. Các giá trị sau đây đã được chỉ định và được máy chủ Google chấp nhận, nhưng không ảnh hưởng đến hoạt động của máy chủ: 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 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 lựa chọn tài khoản cần được tối ưu hoá cho những tài khoản thuộc miền đó. Để tối ưu hóa cho các 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ị cho dấu hoa thị (*): hd=*.

Đừng dựa vào tính năng tối ưu hoá 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ì yêu cầu phía máy khách có thể được sửa đổi. Hãy nhớ xác thực rằng mã thông báo ID trả về có giá trị xác nhận quyền sở hữu hd khớp với giá trị mà 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 mã thông báo hd chứa trong mã thông báo bảo mật của Google, vì vậy giá trị đó có thể đáng tin cậy.

include_granted_scopes (Không bắt buộc) Nếu thông số này được cung cấp cùng 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 đã cấp trước đó cho tổ hợp người dùng/ứng dụng này đối với các phạm vi khác; xem Ủ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 người dùng đang cố xác thực, ứng dụng của bạn 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 trước 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ác vấn đề xảy ra nếu ứng dụng của bạn đăng nhập vào tài khoản người dùng không chính xác. Giá trị này có thể là một địa chỉ email hoặc chuỗi sub, tương đương với mã 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 liệu máy chủ uỷ quyền có nhắc người dùng xác thực lại và đồng ý hay không. Bạn có thể sử dụng các giá trị sau:
  • none

    Máy chủ uỷ quyền không cho thấy bất kỳ màn hình xác thực hoặc sự đồng ý nào của người dùng. Máy chủ uỷ quyền 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 trước đối với các phạm vi đã yêu cầu. Bạn có thể sử dụng none để kiểm tra trạng thái xác thực và/hoặc đồng ý hiện tại.

  • 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 một 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 tại máy chủ ủy quyền chọn trong số nhiều tài khoản mà họ có thể 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 cho phép truy cập, thì màn hình xin phép sẽ hiển thị.

Xác thực mã thông báo

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

Sau đây là một số tình huống thường gặp khi 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 ID với các yêu cầu cần được xác thực. Mã thông báo mã cho bạn biết người dùng cụ thể đang đưa ra yêu cầu và mã ứng dụng nào đã được cấp cho ứng dụng nào.

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

Một điều hữu ích đối với mã thông báo mã nhận dạng là bạn có thể truyền mã thông báo này 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 nhận dạng như một cơ chế xác thực nhẹ để xác thực ứng dụng và người dùng. Nhưng trước khi có thể sử dụng thông tin trong mã thông báo 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 đó.

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

  1. Xác minh rằng công ty phát hành đã ký đúng mã thông báo nhận dạng. Mã thông báo do Google cấp được ký bằng một trong các chứng chỉ có trong 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 bằng 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 khách của ứng dụng.
  4. Kiểm tra để đảm bảo thời gian hết hạn (thông báo xác nhận quyền sở hữu exp) chưa kết thúc.
  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 nhận dạng này có thông báo xác nhận quyền sở hữu hd khớp với một miền được chấp nhận liên kết với một tổ chức Google Cloud.

Các bước 2 đến 5 chỉ bao gồm các 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 ở đây.

Bước đầu tiên phức tạp hơn và 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ộ đã triển khai trên máy chủ hoặc thiết bị. Giả sử giá trị mã thông báo ID 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 ở dạng đối tượng JSON được giải mã.

Điểm cuối tokeninfo hữu ích cho việc gỡ lỗi. Tuy nhiên, để 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 của khoá và thực hiện việc xác thực cục bộ. Bạn nên truy xuất URI khóa 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ị điều tiết hoặc có thể gặp lỗi không liên tục.

Vì Google chỉ thường xuyên thay đổi các khoá công khai, nên bạn có thể lưu các khoá này vào bộ nhớ đệm bằng lệnh bộ nhớ đệm phản hồi HTTP. Và trong phần lớn trường hợp, hãy thực hiện việc xác thực cục bộ một cách hiệu quả hơn nhiều so với việc sử dụng điểm cuối tokeninfo. Quá trình 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ỉ, 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ó nhiều thư viện đã được gỡ lỗi tốt ở nhiều ngôn ngữ để thực hiện việc này (hãy xem jwt.io).

Lấy thông tin tiểu sử người dùng

Để thu thập 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 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 đề ủy quyền và thực hiện yêu cầu GET HTTPS đến điểm cuối thông tin người dùng. Bạn nên truy xuất mã này từ tài liệu Khám phá bằng cách sử dụng giá trị siêu dữ liệu userinfo_endpoint. Thông tin phản hồi của người dùng bao gồm thông tin về người dùng, như mô tả trong phần 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 cho phạm vi truy cập được uỷ quyền.

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à khóa 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 Khám phá", một tài liệu JSON được tìm thấy tại 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 OpenID Connect, bao gồm cả URI của mã xác thực (pointer), mã thông báo, lệnh thu hồi, điểm cuối của khóa công khai và khoá công khai. Tài liệu Khám phá cho dịch vụ OpenID Connect của Google có thể được truy lục từ:

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

Để sử dụng dịch vụ OpenID Connect của Google, bạn cầ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 điểm cuối URI từ đó khi 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.

Dưới đây là một ví dụ về tài liệu nà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 đó để hiểu ý nghĩa của tên). Các giá trị này chỉ mang tính minh họa và có thể thay đổi, mặc dù các bản sao này được sao chép từ một phiên bản tài liệu khám phá thực tế gần đây của Google:

{
  "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 một lượt trọn vòng HTTP bằng cách lưu lại các giá trị từ tài liệu Khám phá. Các tiêu đề bộ nhớ đệm HTTP chuẩn được sử dụng và phải được tuân thủ.

Thư viện ứng dụng

Các thư viện ứng dụng sau đây 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 trong thông số kỹ thuật OpenID Connect Core. Mọi ứng dụng được thiết kế để hoạt động với OpenID Connect phải tương tác với dịch vụ này (ngoại trừ Đối tượng yêu cầu OpenID).