Kết nối OpenID

Điểm cuối OpenID Connect của Google được chứng nhận OpenID.

API OAuth 2.0 của Google có thể được sử dụng cho cả xác thực và ủy 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 theo đặc điểm kỹ thuật của OpenID Connect và được chứng nhận OpenID . Tài liệu tìm thấy trong Sử dụng OAuth 2.0 để truy cập API của Google cũng áp dụng cho dịch vụ này. Nếu bạn muốn khám phá giao thức này một cách tương tác, chúng tôi khuyên bạn nên sử dụng Google OAuth 2.0 Playground . Để nhận trợ giúp về Stack Overflow , hãy gắn thẻ 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 người dùng, bạn phải thiết lập một dự án trong Google API Console để lấy thông tin đăng nhập OAuth 2.0, đặt URI chuyển hướng và (tùy chọn) tùy chỉnh thông tin thương hiệu mà người dùng của bạn nhìn thấy trên người dùng- màn hình đồng ý. Bạn cũng có thể sử dụng API Console để tạo tài khoản dịch vụ, kích hoạt thanh toán, thiết lập lọc và thực hiện các tác vụ khác. Để biết thêm chi tiết, hãy xem Trợ giúp Google API Console .

Nhận bằng chứng xác thực OAuth 2.0

Bạn cần thông tin đăng nhập OAuth 2.0, bao gồm ID ứng dụng khách và bí mật ứ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.

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 các yêu cầu xác thực của bạn.

要创建,查看或编辑给定OAuth 2.0凭据的重定向URI,请执行以下操作:

  1. Go to the Credentials page.
  2. 在页面的OAuth 2.0客户端ID部分中,点击一个凭据。
  3. 查看或编辑重定向URI。

如果“凭据”页面上没有OAuth 2.0客户端ID部分,则您的项目没有OAuth凭据。要创建一个,点击创建凭证

Tùy chỉnh màn hình chấp thuận của 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 bao gồm màn hình chấp thuận mô tả thông tin mà người dùng tiết lộ 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 của bạn bao gồm trong 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 chấp thuận của người dùng cũng hiển thị thông tin thương hiệu như tên sản phẩm, biểu trưng và URL trang chủ của bạn. Bạn kiểm soát thông tin 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 những gì 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, nó 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 để quản lý nhiều chi tiết triển khai của việc xác thực người dùng và giành quyền truy cập vào các API của Google. Ví dụ bao gồm Đăng nhập bằng Google và các thư viện ứng dụng khách của Google , có sẵn cho nhiều nền tảng khác nhau.

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, phần này mô tả các luồng yêu cầu HTTP cơ bản là các thư viện có sẵn.

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

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

Các phương pháp được sử dụng phổ biến nhất để xác thực người dùng và lấy mã thông báo ID được gọi là luồng "máy chủ" và luồng "ngầm". Luồng máy chủ cho phép máy chủ back-end 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 sử 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 các API thay vì thông qua máy chủ back-end của nó.

Tài liệu này mô tả cách thực hiện luồng máy chủ để xác thực người dùng. Luồng ngầm phức tạp hơn đáng kể vì 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 bạn cần triển khai một quy trình ngầm, chúng tôi thực sự khuyên bạn nên sử dụng Đăng nhập bằng Google .

Luồng máy chủ

Đảm bảo rằng bạn đã thiết lập ứng dụng của mình 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 của bạn. Khi người dùng cố gắng đă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 tới Google
  3. Xác nhận mã thông báo trạng thái chống giả mạo
  4. Trao đổi code cho mã thông báo truy cập và mã thông báo ID
  5. Lấy thông tin người dùng từ mã thông báo ID
  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 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ã phiên duy nhất 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 đối sánh mã phiên duy nhất này với phản hồi xác thực do dịch vụ Đăng nhập OAuth của Google 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 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ự hoặc hơn được tạo bằng cách sử dụng trình tạo số ngẫu nhiên chất lượng cao. Một thứ 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 bằng một khóa được giữ bí mật trên back-end của bạn.

Đoạn mã sau minh họa việc tạo mã thông báo phiên duy nhất.

PHP

Bạn phải tải xuống thư viện ứng dụng khách API của 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 xuống thư viện ứng dụng Google API 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 xuống thư viện ứng dụng API của 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 tới Google

Bước tiếp theo là hình thành 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 quy trình này; Các kết nối HTTP bị từ chối. Bạn nên lấy URI gốc từ tài liệu Discovery sử dụng authorization_endpoint giá trị siêu dữ liệu. 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 một yêu cầu cơ bản, hãy chỉ định các thông số sau:

  • client_id mà bạn lấy từ API Console Credentials page.
  • response_type , mà trong một 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 , mà trong một yêu cầu cơ bản phải là openid email . (Đọc thêm ở scope .)
  • redirect_uri phải là điểm cuối HTTP trên máy chủ của bạn 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 ủy quyền cho ứng dụng khách 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 URI được ủy quyền, 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ư bất kỳ thông tin nào 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 ra, cho phép 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 ID 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 đang đăng nhập, màn hình chấp thuận sẽ bao gồm yêu cầu chấp thuận để chuyển địa chỉ email của người dùng vào ứng dụng của bạn. (Đọc thêm tại login_hint .)
  • Sử dụng thông số hd để tối ưu hóa luồng OpenID Connect cho người dùng của một miền G Suite cụ thể. (Đọc thêm tại hd .)

Dưới đây là một ví dụ về URI xác thực OpenID Connect hoàn chỉnh, với các dấu ngắt dòng và dấu cách để có thể đọc đượ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 được yêu cầu đồ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 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 câu trả lời được trả về trong chuỗi truy vấn, như được hiển thị bên dưới:

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 bạn đã tạo ở Bước 1 . Xác minh khứ hồi này giúp đảm bảo rằng người dùng, không phải một tập lệnh độc hại, đang đưa ra yêu cầu.

Đoạn mã sau thể hiện 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 xuống thư viện ứng dụng Google API 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 xuống thư viện ứng dụng Google API 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 xuống thư viện ứng dụng API của 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 cho mã thông báo truy cập và mã thông báo ID

Phản hồi bao gồm tham số code , mã ủy quyền một lần mà máy chủ của bạn có thể đổi lấy mã thông báo truy cập và mã thông báo ID. 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 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 tham số sau trong nội dung POST :

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

Yêu cầu thực tế có thể giố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:

Lĩnh vực
access_token Mã thông báo có thể được gửi tới API Google.
expires_in Thời gian tồn tại 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ý điện tử.
scope Các phạm vi truy cập được cấp bởi access_token biểu thị dưới dạng danh sách các chuỗi phân biệt 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ả lại. 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ỉ hiển thị 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), nghĩa là, một đối tượng JSON được mã hóa dựa trên Base64 được ký bằng mật mã. Thông thường, điều quan trọng là bạn phải xác thực mã thông báo ID trước khi sử dụng, nhưng 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 bí mật khách hàng của bạn để xác thực bản thân với Google, bạn có thể tự tin rằng mã thông báo của mình nhận thực sự đến từ Google và hợp lệ. Nếu máy chủ của bạn chuyển mã thông báo ID cho các thành phần khác trong ứng dụng của bạn, 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 việc 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, bạn có thể sẽ kết thúc việc xác thực mã thông báo khi bạn truy cập các xác nhận quyền sở hữu trong mã thông báo ID.

Trọng tải của mã thông báo ID

Mã thông báo ID là một đối tượng JSON chứa một tập hợp các cặp tên / giá trị. Đâ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 ID Google có thể chứa các trường sau (được gọi là xác nhận quyền sở hữu ):

Yêu cầu Đã cung cấp Sự miêu tả
aud luôn luôn Đối tượng mà mã thông báo ID này dành cho. Nó phải là một trong những ID ứng dụng khách OAuth 2.0 của ứng dụng của bạn.
exp luôn luôn Thời gian hết hạn vào hoặc sau đó mà mã thông báo ID không được chấp nhận. Được biểu diễn theo thời gian Unix (số nguyên giây).
iat luôn luôn Thời gian mã thông báo ID được phát hành. Được biểu diễn theo thời gian Unix (số nguyên giây).
iss luôn luôn Mã định danh Nhà phát hành cho Người 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 ID Google.
sub luôn luôn Một số nhận dạng cho người dùng, duy nhất trong số tất cả các tài khoản Google và không bao giờ được sử 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 khóa nhận dạng duy nhất cho người dùng. Độ dài tối đa 255 ký tự ASCII phân biệt chữ hoa chữ thường.
at_hash Băm mã thông báo truy cập. Cung cấp 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 ID được cấp với giá trị access_token trong luồng máy chủ, xác nhận quyền sở hữu này luôn được bao gồm. Xác nhận quyền sở hữu này có thể được sử dụng như một 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, nhưng nếu bạn làm theo Bước 1Bước 3 thì không cần xác minh mã thông báo truy cập.
azp client_id của người trình bày được ủy quyền. 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 ID không giống với đối tượng của mã thông báo ID. Đâ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 nhau nhưng chia sẻ cùng 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 cho người dùng này và không thích 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 Đúng nếu địa chỉ e-mail của người dùng đã được xác minh; ngược lại là sai.
family_name (Các) họ hoặc (các) họ của người dùng. Có thể được cung cấp khi có yêu cầu về name .
given_name (Các) tên hoặc (các) tên đã cho của người dùng. Có thể được cung cấp khi có yêu cầu về name .
hd Miền G Suite được lưu trữ của người dùng. Chỉ được cung cấp nếu người dùng thuộc miền được 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 về 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 ID được trả lại từ quá trình làm mới mã thông báo

Khi có các xác nhận quyền sở hữu name , bạn có thể sử dụng chúng để cập nhật hồ sơ người dùng ứng dụng của mình. Lưu ý rằng yêu cầu này không bao giờ được đảm bảo sẽ có mặt.

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 nó chỉ xuất hiện một lần.
picture URL của ả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 ID được trả lại từ quá trình làm mới mã thông báo

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

profile URL của 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 ID được trả lại từ quá trình làm mới mã thông báo

Khi có các xác nhận quyền sở hữu profile , bạn có thể sử dụng chúng để cập nhật hồ sơ người dùng ứng dụng của mình. Lưu ý rằng yêu cầu này không bao giờ được đảm bảo sẽ có mặt.

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

Sau khi lấy 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 của Google đáp ứng tất cả cá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 của mình. Bạn có thể tự động đăng ký 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ó thể điền trước nhiều trường mà bạn yêu cầu trên biểu mẫu đăng ký của mình. 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 đ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 các nhà phát triển có yêu cầu nâng cao về xác thực và ủy quyền.

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ể thay mặt người dùng cho phép sử dụng các API Google khác (chẳng hạn như YouTube, Google Drive, Lịch hoặc Danh bạ) khi bạn xác thực người dùng. Để thực hiện việc này, hãy bao gồm các phạm vi khác mà bạn cần trong yêu cầu xác thực mà bạn gửi tới 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 của bạn, hãy chuyển tham số phạm vi của 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ã thông báo truy cập mà bạn nhận lại từ Google cho phép 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.

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ã 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ã thông báo làm mới, hãy thêm đặt tham số access_type thành offline trong yêu cầu xác thực của bạn.

Cân nhắc:

  • Đảm bảo 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ó cá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 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ả cá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, nó 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ũ hơn sẽ ngừng hoạt động.

Để biết thêm thông tin, hãy xem 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 ủy quyền lại ứng dụng của mình bằng cách đặt thông số prompt consent trong yêu cầu xác thực của bạn. Khi có prompt=consent , màn hình đồng ý sẽ hiển thị mỗi khi ứng dụng của bạn yêu cầu ủy quyền các phạm vi truy cập, ngay cả khi trước đó tất cả các phạm vi đã được cấp cho dự án Google API 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ề 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 cung cấp mô tả đầy đủ hơn về các tham số được chấp nhận bởi API xác thực OAuth 2.0 của Google.

Tham số Cần thiết Sự miêu tả
client_id (Cần thiết) Chuỗi ID ứng dụng khách mà bạn lấy từ API Console Credentials page, như được mô tả trong Lấy bằng chứng xác thực OAuth 2.0 .
nonce (Cần thiết) 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ệ phát lại.
response_type (Cần thiết) Nếu giá trị là code , hãy khởi chạy dòng mã ủy quyền Cơ bản , yêu cầu POST tới điểm cuối mã thông báo để lấy mã. Nếu giá trị là token id_token hoặc id_token token , khởi chạy một quy trình 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ừ mã định danh #fragment URI .
redirect_uri (Cần thiết) 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 ủy quyền mà bạn đặt trong API Console Credentials page (bao gồm lược đồ HTTP hoặc HTTPS, trường hợp và dấu '/', nếu có).
scope (Cần thiết)

Tham số phạm vi phải bắt đầu bằng giá trị openid và 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 được đảm bảo) bao gồm các 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 hiện diện, mã thông báo ID bao gồm 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 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 có sẵn, hãy xem Phạm vi OAuth 2.0 dành cho API Google hoặc tài liệu dành cho API Google mà bạn muốn sử dụng.

state (Tùy chọn, nhưng đặc biệt khuyến khích)

Một chuỗi không rõ ràng được cắt vòng trong giao thức; có nghĩa là, nó được trả về dưới dạng tham số URI trong Luồng cơ bản và trong #fragment định danh URI #fragment trong luồng ngầm định.

state có thể hữu ích cho các yêu cầu và phản hồi tương quan. Bởi vì redirect_uri của bạn có thể được đoán, việc sử dụng giá trị state có thể làm tăng sự đảm bảo của bạn rằng kết nối đến là kết quả của một 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ã hóa băm của một số trạng thái máy khách (ví dụ: cookie) trong biến state này, bạn có thể xác thực phản hồi để đảm bảo thêm rằng yêu cầu và phản hồi bắt nguồn từ cùng một trình duyệt. Điều này cung cấp khả năng bảo vệ chống lại 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) Các giá trị được phép là offlineonline . Hiệu ứng được ghi lại trong Truy cập Ngoại tuyến ; nếu mã thông báo truy cập đang được yêu cầu, máy khách sẽ không nhận được mã làm mới trừ khi một giá trị offline được chỉ định.
display (Không bắt buộc) Giá trị chuỗi ASCII để chỉ định cách máy chủ ủy 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 có bất kỳ ảnh hưởng nào đến hoạt động của nó: page , popup , touchwap .
hd (Không bắt buộc)

Thông số hd (miền được lưu trữ) hợp lý hóa quy trình đăng nhập cho các tài khoản được lưu trữ trên G Suite. Bằng cách bao gồm miền của người dùng G Suite (ví dụ: mycollege.edu ), bạn có thể chỉ ra rằng giao diện người dùng lựa chọn tài khoản phải được tối ưu hóa cho các tài khoản tại miền đó. Để tối ưu hóa cho các tài khoản G Suite nói chung thay vì chỉ một miền, hãy đặt giá trị của dấu hoa thị ( * ): hd=* .

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

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 ủy quyền được cấp, ủy quyền sẽ bao gồm mọi ủy 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; xem Ủy quyền tăng dần .

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

login_hint (Không bắt buộc) Khi ứng dụng của bạn biết người dùng nào nó đang cố gắng xác thực, nó có thể cung cấp thông số này như một gợi ý cho máy chủ xác thực. Việc chuyển gợi ý này sẽ ngăn 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 phù hợp (nếu người dùng đang sử dụng đăng nhập nhiều tài khoản ), điều này có thể giúp bạn tránh các sự cố xảy ra nếu ứng dụng của bạn đăng nhập sai tài khoản người dùng. Giá trị có thể là địa chỉ email hoặc chuỗi sub , tương đương với ID 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ủ ủ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ể là:
  • none

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

  • consent

    Máy chủ ủy quyền 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ủ ủy 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ó các phiên hiện tại.

Nếu không có giá trị nào được chỉ định và người dùng chưa cấp quyền truy cập trước đó, thì người dùng sẽ hiển thị màn hình đồng ý.

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

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

Sau đây là các tình huống phổ biến mà bạn có thể gửi mã thông báo ID đế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 ID cho bạn biết người dùng cụ thể thực hiện yêu cầu và mã thông báo ID đó đã được cấp cho khách hàng nào.

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

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

Việc xác thực mã thông báo ID yêu cầu một số bước:

  1. Xác minh rằng mã thông báo ID được nhà phát hành ký đúng cách. Mã thông báo do Google cấp được ký bằng một trong các chứng chỉ được tìm thấy 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 yêu cầu iss trong mã thông báo ID bằng https://accounts.google.com hoặc accounts.google.com .
  3. Xác minh rằng giá trị của aud khẳng định trong thẻ ID bằng ID của khách hàng ứng dụng của bạn.
  4. Xác minh rằng thời gian hết hạn ( exp khẳng định) của thẻ ID đã không được thông qua.
  5. Nếu bạn đã chỉ định giá trị thông số hd trong yêu cầu, hãy xác minh rằng mã thông báo ID có xác nhận quyền sở hữu hd khớp với miền được lưu trữ trên máy chủ G Suite được chấp nhận.

Các bước từ 2 đến 5 chỉ liên quan đến so sánh chuỗi và ngày khá đơn giản, vì vậy chúng tôi sẽ không trình bày chi tiết ở đâ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ật mã. Đối với mục đích 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 ID của bạn là XYZ123 . Sau đó, bạn sẽ tham khảo URI https://oauth2.googleapis.com/tokeninfo?id_token= XYZ123 . Nếu chữ ký mã thông báo hợp lệ, phản hồi sẽ là trọng tải JWT ở dạng đối tượng JSON được giải mã của nó.

Điểm cuối tokeninfo hữu ích để gỡ lỗi nhưng cho mục đích sản xuất, hãy truy xuất khóa công khai của Google từ điểm cuối khóa và thực hiện 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 giá trị siêu dữ liệu jwks_uri . Các yêu cầu tới điểm cuối gỡ lỗi có thể bị điều chỉnh hoặc có thể bị lỗi gián đoạn.

Vì Google chỉ thay đổi khóa công khai của mình một cách không thường xuyên, bạn có thể lưu chúng vào bộ nhớ cache bằng cách sử dụng chỉ thị bộ nhớ cache của phản hồi HTTP và trong phần lớn các trường hợp, thực hiện xác thực cục bộ hiệu quả hơn nhiều so với việc sử dụng điểm cuối tokeninfo . Việc xác thực này yêu cầu truy xuất và phân tích cú pháp 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 thay, có các thư viện được gỡ lỗi tốt có sẵn bằng nhiều ngôn ngữ khác nhau để thực hiện điều 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ã thông báo truy cập (mà ứng dụng của bạn nhận được trong quá 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 của mình.

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

    scope=openid%20profile%20email
  2. Thêm mã thông báo truy cập của bạn vào tiêu đề ủy quyền và thực hiện yêu cầu HTTPS GET tới điểm cuối userinfo, mà bạn sẽ truy xuất từ tài liệu Khám phá bằng giá trị siêu dữ liệu userinfo_endpoint . Câu trả lời UserInfo bao gồm thông tin về người dùng, như mô tả trong OpenID Connect Standard Claimsclaims_supported giá trị siêu dữ liệu 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 phép của bạ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 hóa 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á", tài liệu JSON được tìm thấy tại một vị trí nổi tiếng có chứa các cặp khóa-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ác URI của ủy quyền , mã thông báo, thu hồi, userinfo và các điểm cuối khóa công khai. Tài liệu Khám phá cho dịch vụ OpenID Connect của Google có thể được truy xuất 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ố định 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 quy tắc bộ nhớ đệm trong phản hồi, sau đó truy xuất các URI điểm cuối từ nó nếu cần. Ví dụ, để xác thực người dùng, mã của bạn sẽ lấy lại authorization_endpoint giá trị siêu dữ liệu ( https://accounts.google.com/o/oauth2/v2/auth trong ví dụ dưới đây) như là cơ sở cho các yêu cầu URI xác thực được gửi đến Google.

Đây là một 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ị hoàn toàn mang tính minh họa 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 Google Discovery thực tế:

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

Thư viện khách hàng

Các thư viện ứng dụng khách sau giúp việc triển khai OAuth 2.0 đơn giản hơn bằng cách tích hợp với các khuôn khổ 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 thông số kỹ thuật OpenID Connect Core . Bất kỳ ứng dụng khách nào đượ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 ).