Bạn có thể dùng API OAuth 2.0 của Google cho cả hoạt động xác thực và uỷ quyền. Tài liệu này mô tả việc triển khai OAuth 2.0 của chúng tôi để xác thực, tuân thủ quy cách OpenID Connect và được OpenID chứng nhận. Tài liệu trong phần 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 một cách tương tác, bạn nên sử dụng Google OAuth 2.0 Playground. Để được trợ giúp trên Stack Overflow, hãy gắn thẻ "google-oauth" cho câu hỏi của bạn.
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 người dùng, bạn phải thiết lập một dự án trong để 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) tuỳ chỉnh thông tin thương hiệu mà người dùng nhìn thấy trên màn hình đồng ý của người dùng. Bạn cũng có thể dùng để tạo tài khoản dịch vụ, bật tính năng thanh toán, thiết lập bộ 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.
Lấy thông tin đăng nhập OAuth 2.0
Bạn cần có thông tin xác thực OAuth 2.0, bao gồm cả mã ứng dụng khách và khoá bí mật của ứng dụng khách, để xác thực người dùng và có quyền truy cập vào các API của Google.
Để xem ID khách hàng và bí mật của máy khách đối với thông tin xác thực OAuth 2.0, nhấp vào văn bản sau: Chọn thông tin xác thực . Trong cửa sổ mở ra, chọn dự án của bạn và thông tin đăng nhập bạn muốn, sau đó bấm Xem .
Hoặc, xem ID khách hàng và bí mật khách hàng của bạn từ trang Thông tin xác thực trong API Console :
- Go to the Credentials page.
- Nhấp vào tên của thông tin đăng nhập của bạn hoặc biểu tượng bút chì ( create ). ID khách hàng và bí mật của bạn nằm ở đầu trang.
Đặt URI chuyển hướng
URI chuyển hướng mà bạn đặt trong sẽ xác định nơi Google gửi phản hồi cho các 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:
- Go to the Credentials page.
- 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.
- 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 .
Tuỳ chỉnh màn hình đồng ý của 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ột 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
. Ứng dụng của bạn sẽ đưa tham số này vào 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 đồng ý của người dùng cũng trình bày thông tin thương hiệu như tên sản phẩm, biểu trưng và URL trang chủ. Bạn có quyền kiểm soát thông tin thương hiệu trong .
Để bật màn hình đồng ý của dự án của bạn:
- Mở Consent Screen page trong Google API Console .
- If prompted, select a project, or create a new one.
- Đ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 những gì người dùng sẽ thấy khi có sự kết hợp giữa OAuth 2.0 và các phạm vi Google Drive trong yêu cầu. (Hộp thoại chung này được tạo bằng Google OAuth 2.0 Playground, nên không bao gồm thông tin thương hiệu sẽ được đặt trong .)

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ể dùng để xử lý nhiều chi tiết triển khai về việc xác thực người dùng và có quyền truy cập vào các API của Google. Ví dụ: Dịch vụ nhận dạng của Google và thư 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. Tài liệu này mô tả các luồng yêu cầu HTTP làm cơ sở cho các thư viện hiện có.
Xác thực người dùng
Xác thực người dùng bao gồm việc lấy mã nhận dạng và xác thực mã đó. Mã thông báo 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 câu khẳng định về danh tính trên Internet.
Các phương pháp thường dùng nhất để xác thực người dùng và lấy mã nhận dạng là luồng "máy chủ" và luồng "ngầm". 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 đang sử dụng trình duyệt hoặc thiết bị di động. Luồng ngầm đượ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ì dùng máy chủ phụ trợ.
Tài liệu này mô tả cách thực hiện quy trình phía máy chủ để xác thực người dùng. Luồng ngầm ẩn phức tạp hơn đáng kể do các rủi ro bảo mật trong việc 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 luồng ngầm, bạn nên sử dụng Dịch vụ nhận dạng của Google.
Luồng máy chủ
Đảm bảo bạn thiết lập ứng dụng của mình trong để 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ố gắng đăng nhập bằng Google, bạn cần:
- Tạo mã thông báo trạng thái chống giả mạo
- Gửi yêu cầu xác thực đến Google
- Xác nhận mã thông báo trạng thái chống giả mạo
- Trao đổi
code
để lấy mã truy cập và mã nhận dạng - Lấy thông tin người dùng từ mã thông báo nhận dạng
- 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ệ sự an toàn 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à máy 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 bằng Google OAuth trả về để xác minh rằng người dùng đang thực hiện yêu cầu chứ không phải kẻ tấn công độc hại. Những mã thông báo này thường được gọi là mã thông báo chống giả mạo yêu cầu trên nhiều trang web (CSRF).
Một lựa chọn phù hợp cho mã thông báo trạng thái 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 cách khác là tạo một hàm băm 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 trên phần phụ trợ của bạn.
Đoạ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 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 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 đến Google
Bước tiếp theo là tạo yêu cầu HTTPS GET
bằng 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 quy trình này; các 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
. Thảo luận sau đây giả định rằng 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ừ .response_type
. Trong yêu cầu cơ bản về quy trình sử dụng mã uỷ quyền, tham số này phải làcode
. (Đọc thêm tạiresponse_type
.)scope
. Trong một yêu cầu cơ bản, tham số này phải làopenid email
. (Đọc thêm tạiscope
.)redirect_uri
phải là điểm cuối HTTP trên máy chủ của bạn, nơi sẽ nhận được phản hồi từ Google. Giá trị 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 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à trả về lỗiredirect_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 bối 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ạistate
.)nonce
là một giá trị ngẫu nhiên do ứng dụng của bạn tạo ra, cho phép bảo vệ chống 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ỗisub
, tương đương với mã nhận dạng Google của người dùng. Nếu bạn không cung cấplogin_hint
và người dùng đã đăng nhập, thì màn hình đồng ý 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ủa bạn. (Đọc thêm tạilogin_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ể được liên kết với một tổ chức Google Workspace hoặc Cloud (đọc thêm tạihd
).
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 của bạn 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ả các phản hồi đều được trả về trong chuỗi truy vấn:
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 xác minh 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ạ cách 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 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 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. Trao đổi code
để lấy mã truy cập và mã nhận dạng
Phản hồi này bao gồm một tham số code
, một mã uỷ quyền dùng 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 thực hiện trao đổi này bằng cách gửi một yêu cầu HTTPS POST
. Yêu cầu POST
được gửi đến điểm cuối của mã thông báo. Bạn nên truy xuất điểm cuối này từ Tài liệu khám phá bằng cách sử dụng giá trị siêu dữ liệu token_endpoint
. Thảo luận sau đây giả định rằng điểm cuối là https://oauth2.googleapis.com/token
. Yêu cầu phải bao gồm các tham số sau trong nội dung POST
:
Trường | |
---|---|
code |
Mã uỷ quyền được trả về từ yêu cầu ban đầu. |
client_id |
Mã ứng dụng mà bạn nhận được từ , như mô tả trong phần Lấy thông tin đăng nhập OAuth 2.0. |
client_secret |
Khoá bí mật của ứng dụng mà bạn nhận được từ , như mô tả trong phần Lấy 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 đã cho được chỉ định trong
, 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 quy cách 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 đến một API của Google. |
expires_in |
Thời gian còn lại của mã 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ý điện tử. |
scope |
Phạm vi truy cập do access_token cấp được thể hiện dưới dạng 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 bạn đặt tham số |
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), tức là một đối tượng JSON được mã hoá Base64 và được ký bằng mật mã. Thông thường, bạn cầ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ì đang giao tiếp trực tiếp với Google qua một kênh HTTPS không có bên trung gian và sử dụng khoá bí mật của ứng dụng để xác thực chính mình với Google, nên bạn có thể tin tưởng 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ủ của bạn truyền mã thông báo nhận dạng đến các thành phần khác của ứng dụng, thì điều cực kỳ quan trọng là 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 quá trình xác thực với 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 mã thông báo dù sao đi nữa khi truy cập vào các xác nhận quyền sở hữu trong mã thông báo nhận dạng.
Tải trọng của mã nhận dạng
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ị. Sau đây là một 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 nhận dạng của Google có thể chứa các trường sau (được gọi là claim):
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 nhận dạng này dành cho. Đây phải là một trong các mã ứng dụng OAuth 2.0 của ứng dụng. |
exp |
mọi lúc | Thời gian hết hạn mà sau thời gian đó, mã thông báo nhận dạng sẽ không được chấp nhận. Được biểu thị bằng thời gian bắt đầu của hệ thống Unix (số giây 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 thời gian bắt đầu của hệ thống Unix (số giây nguyên). |
iss |
mọi lúc | Giá trị nhận dạng tổ chức phát hành cho Tổ chức phát hành của phản hồi. Luôn là https://accounts.google.com hoặc accounts.google.com đối với mã thông báo nhận dạng Google. |
sub |
mọi lúc | Giá trị nhận dạng của người dùng, là giá trị duy nhất trong số tất cả Tài khoản Google và không bao giờ được dùng lại. Một Tài khoản Google có thể có nhiều địa chỉ email tại các thời điểm khác nhau, nhưng giá trị sub không bao giờ thay đổi. Sử dụng sub trong ứng dụng của bạn làm khoá giá trị nhận dạng duy nhất cho người dùng. Độ dài tối đa là 255 ký tự ASCII có phân biệt chữ hoa chữ thường. |
at_hash |
Giá trị băm của mã truy cập. Cung cấp thông tin xác thực rằng mã truy cập được liên kết với mã thông báo nhận dạng. Nếu mã thông báo nhận dạng được phát hành với giá trị access_token trong luồng máy chủ, thì yêu cầu này luôn được đưa vào. Bạn có thể dùng xác nhận quyền sở hữu này làm cơ chế thay thế để chống lại 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 làm theo Bước 1 và Bước 3 thì bạn không cần xác minh mã truy cập. |
|
azp |
client_id của người trình bày được uỷ quyền. Bạn chỉ cần khai báo này khi bên yêu cầu mã thông báo nhận dạng không giống với đối tượng của mã thông báo nhận dạng. Đây có thể là trường hợp tại Google đối với các ứng dụng kết hợp, trong đó một ứng dụng web và ứng dụng Android có client_id OAuth 2.0 khác nhau nhưng dùng chung một dự án API của Google. |
|
email |
Địa chỉ email của người dùng. Chỉ được cung cấp nếu bạn đưa phạm vi email vào yêu cầu. Giá trị của thông tin xác nhận này có thể không phải là giá trị duy nhất cho tài khoản này và có thể thay đổi theo thời gian. Do đó, bạn không nên sử dụng giá trị này làm giá trị nhận dạng chính để liên kết với bản ghi người dùng. Bạn cũng không thể dựa vào miền của yêu cầu email để xác định người dùng của các tổ chức Google Workspace hoặc Cloud; thay vào đó, hãy sử dụng yêu cầu hd .
|
|
email_verified |
Giá trị là true nếu địa chỉ email của người dùng đã được xác minh; nếu không thì giá trị là false. | |
family_name |
Họ của người dùng. Có thể được cung cấp khi có yêu cầu name . |
|
given_name |
(Các) tên hoặc(các) tên riêng của người dùng. Có thể được cung cấp khi có yêu cầu name . |
|
hd |
Miền được liên kết với tổ chức Google Workspace hoặc 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 trên Google Cloud. Bạn phải kiểm tra thông báo xác nhận quyền sở hữu này khi hạn chế quyền truy cập vào một tài nguyên chỉ dành cho thành viên của một số miền nhất định. Việc thiếu xác nhận quyền sở hữu này cho biết rằng tài khoản không thuộc về một miền do Google lưu trữ. | |
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 có yêu cầ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:
Khi có các yêu cầu xác nhận quyền sở hữu |
|
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 bảo vệ khỏi các cuộc tấn công phát lại bằng cách chỉ trình bày giá trị này một lần. |
|
picture |
URL của ảnh hồ sơ người dùng. Có thể được cung cấp khi:
Khi có các yêu cầu xác nhận quyền sở hữu |
|
profile |
URL của trang hồ sơ người dùng. Có thể được cung cấp khi:
Khi có các yêu cầu xác nhận quyền sở hữu |
6. Xác thực người dùng
Sau khi lấy thông tin người dùng từ mã 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, thì bạn nên bắt đầu một phiên ứng dụng cho người dùng đó nếu phản hồi của Google API đáp ứng mọi yêu cầu đăng nhập.
Nếu người dùng không có 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ý người dùng dựa trên thông tin nhận được từ Google, hoặc ít nhất bạn có thể điền sẵn nhiều trường mà bạn yêu cầu trên biểu mẫu đăng ký. Ngoài thông tin trong mã thông báo nhận dạng, 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 OAuth 2.0 của Google. Thông tin này dành cho những nhà phát triển có các yêu cầu nâng cao về việc 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 ích 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 cấp 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 khi bạn xác thực người dùng. Để làm việc này, hãy thêm 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 đến 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 một cách thích hợp trên màn hình yêu cầu đồng ý. Mã truy cập mà bạn nhận được từ Google sẽ cho phép ứng dụng của bạn truy cập vào tất cả các API liên quan đến phạm vi truy cập mà bạn đã yêu cầu và được cấp.
Mã làm mới
Trong yêu cầu truy cập API, bạn có thể yêu cầu mã làm mới được trả về trong quá trình trao đổi code
. Mã làm mới giúp ứng dụng của bạn có quyền truy cập liên tục vào các API của Google ngay cả khi người dùng không có 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.
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ã làm mới được cấp: một giới hạn cho mỗi 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ả cá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, thì ứng dụng có thể gặp phải những giới hạn này. Trong trường hợp đó, các mã làm mới cũ sẽ ngừng hoạt động.
Để biết thêm thông tin, hãy xem phần Làm mới mã truy cập (quyền truy cập ngoại tuyến).
Yêu cầu người dùng đồng ý lại
Bạn có thể nhắc người dùng uỷ quyền lại cho ứng dụng của mình bằng cách đặt tham 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 đồng ý sẽ xuất hiện mỗi khi ứng dụng của bạn yêu cầu uỷ quyền cho các phạm vi truy cập, ngay cả khi tất cả các phạm vi đã được cấp cho dự án API Google của bạn trước đó. Vì lý do này, bạn chỉ nên thêm prompt=consent
khi cần thiết.
Để biết thêm thông tin về tham 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 đây mô tả đầy đủ hơn về các tham 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 khách mà bạn nhận được từ , như mô tả trong phần 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, cho phép bảo vệ chống phát lại. |
response_type |
(Bắt buộc) | Nếu giá trị là code , hãy khởi chạy Quy trình mã uỷ quyền cơ bản, yêu cầu 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 Luồng ngầm, 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 URI #fragment . |
redirect_uri |
(Bắt buộc) | Xác định nơi gửi phản hồ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 (bao gồm cả lược đồ HTTP hoặc HTTPS, trường hợp và dấu "/" ở cuối, nếu có). |
scope |
(Bắt buộc) | Tham số phạm vi phải bắt đầu bằng giá trị Nếu có giá trị phạm vi Nếu có giá trị phạm vi 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 có quyền truy cập vào từng tệp trong Google Drive của người dùng, thì tham số phạm vi của bạn có thể là Để biết thông tin về các phạm vi hiện có, hãy xem Phạm vi OAuth 2.0 cho các API của Google hoặc tài liệu về API của 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 không rõ ràng được truyền qua lại trong giao thức; tức là chuỗi này được trả về dưới dạng một tham số URI trong quy trình Cơ bản và trong giá trị nhận dạng URI
|
access_type |
(Không bắt buộc) | Các giá trị hợp lệ là offline và online . Hiệu ứng này được ghi lại trong Quyền truy cập khi không có mạng; 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ừ phi bạn chỉ định giá trị offline . |
display |
(Không bắt buộc) | 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 được chỉ định và được máy chủ Google chấp nhận, nhưng không ảnh hưởng đến hành vi của luồng giao thức: page , popup , touch và wap . |
hd |
(Không bắt buộc) | Đơn giản hoá quy trình đăng nhập cho các tài khoản thuộc sở hữu của một tổ chức trên Google Cloud. 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 chọn tài khoản cần được tối ưu hoá cho các tài khoản tại miền đó. Để tối ưu hoá cho các tài khoản tổ chức trên Google Cloud nói chung thay vì chỉ một miền tổ chức trên Google Cloud, hãy đặt giá trị là dấu hoa thị ( Đừng dựa vào việc tối ưu hoá giao diện người dùng này để kiểm soát những người có thể truy cập vào ứng dụng của bạn, vì các yêu cầu phía máy khách có thể bị sửa đổi. Hãy nhớ xác thực rằng mã thông báo nhận dạng đã trả về có giá trị yêu cầu |
include_granted_scopes |
(Không bắt buộc) | Nếu tham số này được cung cấp với giá trị true và yêu cầu uỷ quyền được cấp, thì yêu cầu uỷ quyền sẽ bao gồm mọi yêu cầu uỷ quyền trước đó được cấp cho tổ hợp người dùng/ứng dụng này cho các phạm vi khác; hãy xem phần Uỷ quyền gia tăng.
Xin lưu ý rằng bạn không thể thực hiện uỷ quyền gia tăng bằng quy trình Ứng dụng đã cài đặt. |
login_hint |
(Không bắt buộc) | Khi biết người dùng mà ứng dụng đang cố gắng xác thực, ứng dụng có thể cung cấp tham số này làm gợi ý cho máy chủ xác thực. Việc truyền gợi ý này sẽ ngăn bộ chọn tài khoản xuất hiện và điền sẵn vào hộp email trên biểu mẫu đăng nhập hoặc chọn phiên phù hợp (nếu người dùng đang sử dụng tính năng đăng nhập bằng 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ị có thể là đị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) | Một 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ủ uỷ 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ể là:
Nếu bạn không chỉ định giá trị và người dùng chưa từng uỷ quyền truy cập trước đó, thì người dùng sẽ thấy màn hình đồng ý. |
Xác thực mã 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ừ phi bạn biết rằng các mã thông báo đó đến trực tiếp từ Google. Ví dụ: máy chủ của bạn phải xác minh mọi mã nhận dạng (ID) mà máy chủ nhận được từ ứng dụng khách của bạn là mã nhận dạng xác thực.
Sau đây là những trường hợp phổ biến mà bạn có thể gửi mã nhận dạng đến máy chủ của mình:
- Gửi mã nhận dạng (ID) cùng với những yêu cầu cần được xác thực. Mã thông báo nhận dạng cho bạn biết người dùng cụ thể đưa ra yêu cầu và ứng dụng nào đã cấp mã thông báo nhận dạng đó.
Mã nhận dạng người dùng là thông tin 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ý an toàn bằng cách chỉ truyền chúng qua HTTPS và chỉ sử dụng 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ủ, bạn cũng phải lưu trữ chúng một cách an toàn.
Một điều khiến mã nhận dạng hữu ích là bạn có thể truyền mã nhận dạng này đến nhiều 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ã nhận dạng làm cơ chế xác thực đơn giản để 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 nhận dạng hoặc dựa vào thông tin đó như một khẳng định 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ã nhận dạng, bạn cần thực hiện một số bước:
- Xác minh rằng mã thông báo nhận dạng được nhà phát hành ký đúng cách. Mã thông báo do Google phát hành được ký bằng một trong các 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á. - Xác minh rằng giá trị của khai báo
iss
trong mã thông báo nhận dạng bằng vớihttps://accounts.google.com
hoặcaccounts.google.com
. - Xác minh rằng giá trị của khai báo
aud
trong mã nhận dạng người dùng bằng với mã ứng dụng khách của ứng dụng. - Xác minh rằng thời gian hết hạn (yêu cầu
exp
) của mã thông báo nhận dạng chưa hết. - Nếu bạn chỉ định giá trị tham số hd trong yêu cầu, hãy xác minh rằng mã thông báo nhận dạng có một giá trị
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 trên Google Cloud.
Các bước từ 2 đến 5 chỉ liên quan đến việc so sánh chuỗi và ngày tháng khá đơn giản, vì vậy chúng ta 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à liên quan đến việc kiểm tra chữ ký mã hoá. Để gỡ lỗi, bạn có thể sử dụng điểm cuối tokeninfo
của Google để so sánh với quy 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 hợp lệ, thì phản hồi sẽ là tải trọng JWT ở dạng đối tượng JSON đã giải mã.
Điểm cuối tokeninfo
rất hữu ích cho việc gỡ lỗi, nhưng cho 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 quy trình 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 gỡ lỗi có thể bị điều tiết hoặc gặp phải các lỗi không liên tục.
Vì Google chỉ thay đổi khoá công khai không thường xuyên, nên bạn có thể lưu trữ các khoá này vào bộ nhớ đệm bằng cách sử dụng các chỉ thị bộ nhớ đệm của phản hồi HTTP và trong phần lớn các trường hợp, hãy thực hiện quy trình xác thực cục bộ hiệu quả hơn nhiều so với khi sử dụng điểm cuối tokeninfo
. Quá trình xác thực này yêu cầu 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ã hoá thích hợp để kiểm tra chữ ký. May mắn là có nhiều thư viện đã được gỡ lỗi 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
Để lấy 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 luồng xác thực) và tiêu chuẩn OpenID Connect:
Để tuân thủ OpenID, bạn phải thêm các giá trị phạm vi
openid profile
vào 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 một giá trị phạm vi bổ sung là
email
. Để chỉ định cảprofile
vàemail
, bạn có thể thêm tham số sau vào URI yêu cầu xác thực:scope=openid%20profile%20email
- Thêm mã truy cập vào tiêu đề uỷ quyền và thực hiện yêu cầu HTTPS
GET
đến điểm cuối userinfo. Bạn nên truy xuất điểm cuối này từ Tài liệu khám phá bằng cách sử dụng giá trị siêu dữ liệuuserinfo_endpoint
. Phản hồi userinfo bao gồm thông tin về người dùng, như mô tả trongOpenID Connect Standard Claims
và giá trị siêu dữ liệuclaims_supported
của tài liệu Discovery. 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 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 các tài nguyên, bao gồm cả mã thông báo, thông tin người dùng và khoá công khai.
Để đơn giản hoá việc 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 nằm ở một vị trí quen thuộc 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 các điểm cuối uỷ quyền, mã thông báo, thu hồi, thông tin người dùng và khoá 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ã hoá 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 URI điểm cuối từ tài liệu đó 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à 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 chúng). Các giá trị này chỉ mang tính minh hoạ và có thể thay đổi, mặc dù chúng được sao chép từ phiên bản gần đây của tài liệu Khám phá thực tế 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 chuyến khứ hồi HTTP bằng cách lưu các giá trị vào bộ nhớ đệm từ tài liệu Khám phá. Các tiêu đề lưu vào bộ nhớ đệm HTTP tiêu 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 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).