Tài liệu này giải thích cách triển khai tính năng uỷ quyền OAuth 2.0 để truy cập vào API Google từ một ứng dụng web JavaScript. OAuth 2.0 cho phép người dùng chia sẻ dữ liệu cụ thể với một ứng dụng trong khi vẫn bảo mật tên người dùng, mật khẩu và các thông tin khác. Ví dụ: một ứng dụng có thể sử dụng OAuth 2.0 để xin người dùng cấp quyền lưu trữ tệp trong Google Drive.
Quy trình OAuth 2.0 này được gọi là quy trình cấp quyền ngầm ẩn. API này được thiết kế cho các ứng dụng chỉ truy cập vào API khi người dùng có mặt trong ứng dụng. Những ứng dụng này không thể lưu trữ thông tin mật.
Trong quy trình này, ứng dụng của bạn sẽ mở một URL của Google. URL này sử dụng các tham số truy vấn để xác định ứng dụng và loại quyền truy cập API mà ứng dụng yêu cầu. Bạn có thể mở URL trong cửa sổ trình duyệt hiện tại hoặc cửa sổ bật lên. Người dùng có thể xác thực với Google và cấp các quyền được yêu cầu. Sau đó, Google sẽ chuyển hướng người dùng trở lại ứng dụng của bạn. Lệnh chuyển hướng bao gồm một mã truy cập. Ứng dụng của bạn sẽ xác minh và sau đó dùng mã này để gửi yêu cầu API.
Thư viện ứng dụng API của Google và Dịch vụ nhận dạng của Google
Nếu sử dụng thư viện ứng dụng API của Google dành cho JavaScript để thực hiện lệnh gọi được uỷ quyền đến Google, thì bạn nên dùng thư viện JavaScript của Dịch vụ nhận dạng của Google để xử lý quy trình OAuth 2.0. Vui lòng xem mô hình mã thông báo của Dịch vụ danh tính của Google. Mô hình này dựa trên quy trình cấp quyền ngầm ẩn của OAuth 2.0.
Điều kiện tiên quyết
Bật API cho dự án
Bất kỳ ứng dụng nào gọi API của Google đều cần bật các API đó trong API Console.
Cách bật API cho dự án:
- Open the API Library trong Google API Console.
- If prompted, select a project, or create a new one.
- API Library liệt kê tất cả các API có sẵn, được nhóm theo nhóm sản phẩm và mức độ phổ biến. Nếu API bạn muốn bật không xuất hiện trong danh sách, hãy dùng tính năng tìm kiếm để tìm API đó hoặc nhấp vào Xem tất cả trong nhóm sản phẩm chứa API đó.
- Chọn API bạn muốn bật, sau đó nhấp vào nút Bật.
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
Tạo thông tin uỷ quyền
Mọi ứng dụng dùng OAuth 2.0 để truy cập vào API Google đều phải có thông tin xác thực uỷ quyền giúp nhận dạng ứng dụng đó với máy chủ OAuth 2.0 của Google. Các bước sau đây sẽ giải thích cách tạo thông tin xác thực cho dự án của bạn. Sau đó, ứng dụng của bạn có thể sử dụng thông tin đăng nhập để truy cập vào các API mà bạn đã bật cho dự án đó.
- Go to the Credentials page.
- Nhấp vào Tạo thông tin xác thực > Mã ứng dụng khách OAuth.
- Chọn loại ứng dụng Ứng dụng web.
- Hoàn thành biểu mẫu. Những ứng dụng dùng JavaScript để tạo yêu cầu API Google được cho phép phải chỉ định nguồn gốc JavaScript được cho phép. Nguồn gốc xác định những miền mà ứng dụng của bạn có thể gửi yêu cầu đến máy chủ OAuth 2.0. Những nguồn gốc này phải tuân thủ các quy tắc xác thực của Google.
Xác định phạm vi truy cập
Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên mà ứng dụng cần, đồng thời cho phép người dùng kiểm soát lượng quyền truy cập mà họ cấp cho ứng dụng của bạn. Do đó, có thể có mối quan hệ nghịch đảo giữa số phạm vi được yêu cầu và khả năng có được sự đồng ý của người dùng.
Trước khi bắt đầu triển khai tính năng uỷ quyền OAuth 2.0, bạn nên xác định các phạm vi mà ứng dụng của bạn cần có quyền truy cập.
Tài liệu về Phạm vi API OAuth 2.0 chứa danh sách đầy đủ các phạm vi mà bạn có thể dùng để truy cập vào các API của Google.
Lấy mã truy cập OAuth 2.0
Các bước sau đây cho thấy cách ứng dụng của bạn tương tác với máy chủ OAuth 2.0 của Google để có được sự đồng ý của người dùng nhằm thực hiện yêu cầu API thay mặt người dùng. Ứng dụng của bạn phải có được sự đồng ý đó thì mới có thể thực thi yêu cầu API của Google (yêu cầu phải được người dùng cho phép).
Bước 1: Chuyển hướng đến máy chủ OAuth 2.0 của Google
Để yêu cầu quyền truy cập vào dữ liệu của người dùng, hãy chuyển hướng người dùng đó đến máy chủ OAuth 2.0 của Google.
Điểm cuối OAuth 2.0
Tạo một URL để yêu cầu quyền truy cập từ điểm cuối OAuth 2.0 của Google tại https://accounts.google.com/o/oauth2/v2/auth
. Bạn có thể truy cập điểm cuối này qua HTTPS; các kết nối HTTP thuần tuý sẽ bị từ chối.
Máy chủ uỷ quyền của Google hỗ trợ các tham số chuỗi truy vấn sau đây cho các ứng dụng máy chủ web:
Thông số | |||||||
---|---|---|---|---|---|---|---|
client_id |
Bắt buộc
Mã ứng dụng khách của ứng dụng. Bạn có thể tìm thấy giá trị này trong API Console Credentials page. |
||||||
redirect_uri |
Bắt buộc
Xác định vị trí mà máy chủ API chuyển hướng người dùng sau khi người dùng hoàn tất quy trình uỷ quyền. 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 pagecủa ứng dụng. Nếu giá trị này không khớp với một URI chuyển hướng được uỷ quyền cho Xin lưu ý rằng giao thức, cách viết hoa và dấu gạch chéo |
||||||
response_type |
Bắt buộc
Các ứng dụng JavaScript cần đặt giá trị của tham số thành |
||||||
scope |
Bắt buộc
Một danh sách phạm vi được phân tách bằng dấu cách giúp xác định những tài nguyên mà ứng dụng của bạn có thể thay mặt người dùng truy cập. Những giá trị này thông báo cho màn hình xin phép mà Google hiển thị cho người dùng. Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên mà ứng dụng cần, đồng thời cho phép người dùng kiểm soát lượng quyền truy cập mà họ cấp cho ứng dụng của bạn. Do đó, có mối quan hệ nghịch đảo giữa số phạm vi được yêu cầu và khả năng có được sự đồng ý của người dùng. Ứng dụng của bạn nên yêu cầu quyền truy cập vào phạm vi uỷ quyền trong bối cảnh bất cứ khi nào có thể. Bằng việc yêu cầu quyền truy cập vào dữ liệu người dùng theo bối cảnh, thông qua tính năng uỷ quyền gia tăng, bạn sẽ giúp người dùng dễ dàng hiểu lý do ứng dụng của bạn cần quyền truy cập mà ứng dụng đang yêu cầu. |
||||||
state |
Recommended (Nên dùng)
Chỉ định mọi giá trị chuỗi mà ứng dụng của bạn sử dụng để duy trì trạng thái giữa yêu cầu uỷ quyền và phản hồi của máy chủ uỷ quyền.
Máy chủ sẽ trả về giá trị chính xác mà bạn gửi dưới dạng cặp Bạn có thể sử dụng tham số này cho nhiều mục đích, chẳng hạn như hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi số chỉ dùng một lần và giảm thiểu hành vi giả mạo yêu cầu trên nhiều trang web. Vì có thể đoán được |
||||||
include_granted_scopes |
Không bắt buộc
Cho phép ứng dụng dùng tính năng uỷ quyền gia tăng để yêu cầu quyền truy cập vào các phạm vi khác trong bối cảnh. Nếu bạn đặt giá trị của thông số này thành |
||||||
enable_granular_consent |
Không bắt buộc
Giá trị mặc định là Khi Google bật các quyền chi tiết cho một ứng dụng, tham số này sẽ không có hiệu lực nữa. |
||||||
login_hint |
Không bắt buộc
Nếu ứng dụng của bạn biết người dùng nào đang cố xác thực, thì ứng dụng có thể sử dụng tham số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sử dụng gợi ý để đơn giản hoá quy trình đăng nhập bằng cách điền sẵn trường email trong biểu mẫu đăng nhập hoặc chọn phiên đăng nhập nhiều tài khoản thích hợp. Đặt giá trị tham số thành một địa chỉ email hoặc giá trị nhận dạng |
||||||
prompt |
Không bắt buộc
Danh sách lời nhắc trình bày cho người dùng, được phân tách bằng dấu cách và phân biệt chữ hoa chữ thường. Nếu bạn không chỉ định tham số này, người dùng sẽ chỉ được nhắc vào lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem phần Nhắc nhở người dùng đồng ý lại để biết thêm thông tin. Các giá trị có thể là:
|
Chuyển hướng mẫu đến máy chủ uỷ quyền của Google
Dưới đây là ví dụ về URL, với dấu ngắt dòng và dấu cách để dễ đọc.
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& include_granted_scopes=true& response_type=token& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
Sau khi bạn tạo URL yêu cầu, hãy chuyển hướng người dùng đến URL đó.
Mã mẫu JavaScript
Đoạn mã JavaScript sau đây cho biết cách bắt đầu quy trình uỷ quyền trong JavaScript mà không cần sử dụng Thư viện ứng dụng API của Google cho JavaScript. Vì điểm cuối OAuth 2.0 này không hỗ trợ tính năng Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS), nên đoạn mã sẽ tạo một biểu mẫu để mở yêu cầu đến điểm cuối đó.
/* * Create form to request access token from Google's OAuth 2.0 server. */ function oauthSignIn() { // Google's OAuth 2.0 endpoint for requesting an access token var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth'; // Create <form> element to submit parameters to OAuth 2.0 endpoint. var form = document.createElement('form'); form.setAttribute('method', 'GET'); // Send as a GET request. form.setAttribute('action', oauth2Endpoint); // Parameters to pass to OAuth 2.0 endpoint. var params = {'client_id': 'YOUR_CLIENT_ID', 'redirect_uri': 'YOUR_REDIRECT_URI', 'response_type': 'token', 'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly', 'include_granted_scopes': 'true', 'state': 'pass-through value'}; // Add form parameters as hidden input values. for (var p in params) { var input = document.createElement('input'); input.setAttribute('type', 'hidden'); input.setAttribute('name', p); input.setAttribute('value', params[p]); form.appendChild(input); } // Add form to page and submit it to open the OAuth 2.0 endpoint. document.body.appendChild(form); form.submit(); }
Bước 2: Google nhắc người dùng đồng ý
Ở bước này, người dùng quyết định có cấp cho ứng dụng của bạn quyền truy cập mà họ yêu cầu hay không. Ở giai đoạn này, Google sẽ hiện một cửa sổ đồng ý cho thấy tên ứng dụng của bạn và các dịch vụ API của Google mà Google đang yêu cầu cấp quyền truy cập bằng thông tin xác thực cấp quyền của người dùng và bản tóm tắt về phạm vi quyền truy cập sẽ được cấp. Sau đó, người dùng có thể đồng ý cấp quyền truy cập vào một hoặc nhiều phạm vi mà ứng dụng của bạn yêu cầu hoặc từ chối yêu cầu đó.
Ứng dụng của bạn không cần làm gì ở giai đoạn này vì ứng dụng đang chờ phản hồi từ máy chủ OAuth 2.0 của Google cho biết liệu có quyền truy cập nào đã được cấp hay không. Câu trả lời đó được giải thích trong bước sau.
Lỗi
Các yêu cầu gửi đến điểm cuối uỷ quyền OAuth 2.0 của Google có thể hiển thị thông báo lỗi dành cho người dùng thay vì các quy trình xác thực và uỷ quyền như dự kiến. Dưới đây là các mã lỗi phổ biến và giải pháp được đề xuất.
admin_policy_enforced
Tài khoản Google không thể cấp quyền cho một hoặc nhiều phạm vi theo yêu cầu theo chính sách của quản trị viên Google Workspace của họ. Xem bài viết trợ giúp dành cho Quản trị viên Google Workspace Kiểm soát những ứng dụng nội bộ và ứng dụng bên thứ ba nào truy cập vào dữ liệu Google Workspace để biết thêm thông tin về cách quản trị viên có thể hạn chế quyền truy cập vào tất cả các phạm vi hoặc các phạm vi nhạy cảm và bị hạn chế cho đến khi mã ứng dụng khách OAuth của bạn được cấp quyền truy cập rõ ràng.
disallowed_useragent
Điểm cuối uỷ quyền hiển thị bên trong một tác nhân người dùng nhúng không được Chính sách OAuth 2.0 của Google cho phép.
Android
Nhà phát triển Android có thể gặp phải thông báo lỗi này khi mở yêu cầu uỷ quyền trong android.webkit.WebView
.
Thay vào đó, nhà phát triển nên chuyển sang sử dụng các thư viện Android như Đăng nhập bằng Google cho Android hoặc AppAuth cho Android của OpenSL Foundation.
Các nhà phát triển web có thể gặp phải lỗi này khi ứng dụng Android mở một đường liên kết web chung trong một tác nhân người dùng được nhúng và một người dùng chuyển đến điểm cuối uỷ quyền OAuth 2.0 của Google từ trang web của bạn. Nhà phát triển nên cho phép mở các đường liên kết chung trong trình xử lý đường liên kết mặc định của hệ điều hành, bao gồm cả trình xử lý Đường liên kết trong ứng dụng Android hoặc ứng dụng trình duyệt mặc định. Thư viện Thẻ tuỳ chỉnh của Android cũng là một tuỳ chọn được hỗ trợ.
iOS
Nhà phát triển iOS và macOS có thể gặp phải lỗi này khi mở yêu cầu uỷ quyền trong WKWebView
.
Thay vào đó, nhà phát triển nên sử dụng các thư viện dành cho iOS, chẳng hạn như tính năng Đăng nhập bằng Google dành cho iOS hoặc AppAuth cho iOS của ID mở Foundation.
Các nhà phát triển web có thể gặp phải lỗi này khi một ứng dụng iOS hoặc macOS mở một đường liên kết web chung trong một tác nhân người dùng được nhúng và một người dùng chuyển đến điểm cuối uỷ quyền OAuth 2.0 của Google từ trang web của bạn. Nhà phát triển nên cho phép mở các đường liên kết chung trong trình xử lý đường liên kết mặc định của hệ điều hành, bao gồm cả trình xử lý Đường liên kết phổ quát hoặc ứng dụng trình duyệt mặc định. Thư viện SFSafariViewController
cũng là một tuỳ chọn được hỗ trợ.
org_internal
Mã ứng dụng khách OAuth trong yêu cầu là một phần của dự án giới hạn quyền truy cập vào các Tài khoản Google trong một tổ chức cụ thể trên Google Cloud. Để biết thêm thông tin về lựa chọn cấu hình này, hãy xem phần Loại người dùng trong bài viết trợ giúp Thiết lập màn hình xin phép bằng OAuth.
invalid_client
Nguồn mà yêu cầu được thực hiện không được cấp phép cho ứng dụng này. Hãy xem origin_mismatch
.
invalid_grant
Khi sử dụng tính năng uỷ quyền gia tăng, mã thông báo có thể đã hết hạn hoặc đã hết hiệu lực. Xác thực lại người dùng và yêu cầu sự đồng ý của người dùng để lấy mã thông báo mới. Nếu bạn tiếp tục thấy lỗi này, hãy đảm bảo rằng ứng dụng của bạn đã được định cấu hình đúng cách và bạn đang sử dụng đúng mã thông báo và thông số trong yêu cầu của mình. Nếu không, tài khoản người dùng có thể đã bị xoá hoặc vô hiệu hoá.
origin_mismatch
Giao thức, miền và/hoặc cổng của JavaScript khởi tạo yêu cầu cấp phép có thể không khớp với URI gốc JavaScript được cấp phép đã đăng ký cho mã ứng dụng khách OAuth. Hãy xem xét các nguồn gốc JavaScript được uỷ quyền trong Google API Console Credentials page.
redirect_uri_mismatch
redirect_uri
được truyền trong yêu cầu uỷ quyền không khớp với URI chuyển hướng được uỷ quyền cho mã ứng dụng khách OAuth. Xem lại các URI chuyển hướng được uỷ quyền trong Google API Console Credentials page.
Giao thức, miền và/hoặc cổng của JavaScript khởi tạo yêu cầu cấp phép có thể không khớp với URI gốc JavaScript được cấp phép đã đăng ký cho mã ứng dụng khách OAuth. Hãy xem lại các nguồn gốc JavaScript được uỷ quyền trong Google API Console Credentials page.
Tham số redirect_uri
có thể đề cập đến quy trình OAuth ngoài băng tần (OOB) đã ngừng hoạt động và không còn được hỗ trợ. Hãy tham khảo hướng dẫn di chuyển để cập nhật quy trình tích hợp.
invalid_request
Đã xảy ra lỗi với yêu cầu của bạn. Điều này có thể là do một số lý do:
- Yêu cầu không được định dạng đúng
- Yêu cầu thiếu thông số bắt buộc
- Yêu cầu sử dụng phương thức uỷ quyền mà Google không hỗ trợ. Xác minh rằng bạn đã tích hợp OAuth bằng phương thức tích hợp được đề xuất
Bước 3: Xử lý phản hồi của máy chủ OAuth 2.0
Điểm cuối OAuth 2.0
Máy chủ OAuth 2.0 sẽ gửi phản hồi đến redirect_uri
được chỉ định trong yêu cầu mã truy cập của bạn.
Nếu người dùng phê duyệt yêu cầu, thì phản hồi sẽ chứa mã truy cập. Nếu người dùng không phê duyệt yêu cầu, thì phản hồi sẽ chứa thông báo lỗi. Mã truy cập hoặc thông báo lỗi được trả về trên mảnh băm của URI chuyển hướng, như minh hoạ dưới đây:
Phản hồi về mã truy cập:
https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600
Ngoài tham số
access_token
, chuỗi phân đoạn cũng chứa tham sốtoken_type
(luôn được đặt thànhBearer
) và tham sốexpires_in
chỉ định thời gian tồn tại của mã thông báo (tính bằng giây). Nếu tham sốstate
được chỉ định trong yêu cầu mã truy cập, thì giá trị của tham số đó cũng được đưa vào phản hồi.- Phản hồi lỗi:
https://oauth2.example.com/callback#error=access_denied
Phản hồi mẫu của máy chủ OAuth 2.0
Bạn có thể kiểm thử quy trình này bằng cách nhấp vào URL mẫu sau. URL này yêu cầu quyền chỉ có thể đọc để xem siêu dữ liệu cho các tệp trong Google Drive của bạn:
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& include_granted_scopes=true& response_type=token& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
Sau khi hoàn tất quy trình OAuth 2.0, bạn sẽ được chuyển hướng đến http://localhost/oauth2callback
. URL đó sẽ gây ra lỗi 404 NOT FOUND
trừ phi máy cục bộ của bạn phân phát một tệp tại địa chỉ đó. Bước tiếp theo sẽ cung cấp thêm thông tin chi tiết về thông tin được trả về trong URI khi người dùng được chuyển hướng trở lại ứng dụng của bạn.
Gọi API của Google
Điểm cuối OAuth 2.0
Sau khi ứng dụng của bạn nhận được mã truy cập, bạn có thể sử dụng mã thông báo này để thực hiện lệnh gọi đến một API Google thay mặt cho một tài khoản người dùng cụ thể nếu(các) phạm vi truy cập mà API yêu cầu đã được cấp. Để thực hiện việc này, hãy đưa mã truy cập vào một yêu cầu gửi tới API bằng cách cung cấp tham số truy vấn access_token
hoặc giá trị tiêu đề HTTP Authorization
Bearer
. Khi có thể, bạn nên sử dụng tiêu đề HTTP vì các chuỗi truy vấn thường hiển thị trong nhật ký máy chủ. Trong hầu hết các trường hợp, bạn có thể sử dụng thư viện ứng dụng để thiết lập lệnh gọi đến các API của Google (ví dụ: khi gọi API Tệp trên Drive).
Bạn có thể dùng thử tất cả các API của Google và xem phạm vi của các API đó tại Playground 2.0 của OAuth.
Ví dụ về HTTP GET
Lệnh gọi đến điểm cuối
drive.files
(API Tệp trên Drive) bằng tiêu đề HTTP Authorization: Bearer
có thể có dạng như sau. Lưu ý rằng bạn cần chỉ định mã truy cập của riêng mình:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Dưới đây là lệnh gọi tới cùng một API cho người dùng đã xác thực bằng cách sử dụng tham số chuỗi truy vấn access_token
:
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
Ví dụ về curl
Bạn có thể kiểm thử các lệnh này bằng ứng dụng dòng lệnh curl
. Dưới đây là ví dụ sử dụng tuỳ chọn tiêu đề HTTP (ưu tiên):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
Hoặc cách khác là lựa chọn tham số chuỗi truy vấn:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Mã mẫu JavaScript
Đoạn mã dưới đây minh hoạ cách sử dụng CORS (Chia sẻ tài nguyên nhiều nguồn gốc) để gửi yêu cầu đến một API của Google. Ví dụ này không sử dụng Thư viện ứng dụng API của Google cho JavaScript. Tuy nhiên, ngay cả khi bạn không sử dụng thư viện ứng dụng, hướng dẫn hỗ trợ về ChromeOS trong tài liệu về thư viện đó có thể sẽ giúp bạn hiểu rõ hơn về các yêu cầu này.
Trong đoạn mã này, biến access_token
đại diện cho mã thông báo mà bạn đã nhận được để thay mặt người dùng được uỷ quyền thực hiện các yêu cầu API. Ví dụ đầy đủ minh hoạ cách lưu trữ mã thông báo đó trong bộ nhớ cục bộ của trình duyệt và truy xuất mã đó khi tạo yêu cầu API.
var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://www.googleapis.com/drive/v3/about?fields=user&' + 'access_token=' + params['access_token']); xhr.onreadystatechange = function (e) { console.log(xhr.response); }; xhr.send(null);
Ví dụ đầy đủ
Điểm cuối OAuth 2.0
Mã mẫu này minh hoạ cách hoàn tất quy trình OAuth 2.0 trong JavaScript mà không cần sử dụng Thư viện ứng dụng API của Google cho JavaScript. Mã này dành cho trang HTML hiển thị nút để thử yêu cầu API. Nếu bạn nhấp vào nút này, mã này sẽ kiểm tra xem trang đã lưu trữ mã truy cập API trong bộ nhớ cục bộ của trình duyệt hay chưa. Nếu có, hàm sẽ thực thi yêu cầu API. Nếu không, thao tác này sẽ bắt đầu quy trình OAuth 2.0.
Đối với quy trình OAuth 2.0, trang này sẽ tuân theo các bước sau:
- Đường dẫn này sẽ chuyển người dùng đến máy chủ OAuth 2.0 của Google. Máy chủ này sẽ yêu cầu quyền truy cập vào phạm vi
https://www.googleapis.com/auth/drive.metadata.readonly
. - Sau khi cấp (hoặc từ chối) quyền truy cập vào một hoặc nhiều phạm vi yêu cầu, người dùng sẽ được chuyển hướng đến trang gốc. Trang này sẽ phân tích cú pháp mã truy cập từ chuỗi giá trị nhận dạng mảnh.
Trang này sử dụng mã truy cập để gửi yêu cầu API mẫu.
Yêu cầu API này sẽ gọi phương thức
about.get
của API Drive để truy xuất thông tin về tài khoản Google Drive của người dùng được phép.- Nếu yêu cầu thực thi thành công, thì phản hồi của API sẽ được ghi lại trong bảng điều khiển gỡ lỗi của trình duyệt.
Bạn có thể thu hồi quyền truy cập của ứng dụng đó thông qua trang Quyền của Tài khoản Google. Ứng dụng sẽ được liệt kê là Bản minh hoạ OAuth 2.0 cho Google API Tài liệu.
Để chạy mã này trên máy, bạn cần đặt giá trị cho các biến YOUR_CLIENT_ID
và YOUR_REDIRECT_URI
tương ứng với thông tin xác thực uỷ quyền của bạn. Bạn phải đặt biến YOUR_REDIRECT_URI
thành cùng một URL nơi trang đang được phân phát. 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, bạn sẽ gặp lỗi redirect_uri_mismatch
. Dự án của bạn cũng phải bật API thích hợp cho yêu cầu này.
<html><head></head><body> <script> var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE'; var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE'; // Parse query string to see if page request is coming from OAuth 2.0 server. var fragmentString = location.hash.substring(1); var params = {}; var regex = /([^&=]+)=([^&]*)/g, m; while (m = regex.exec(fragmentString)) { params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); } if (Object.keys(params).length > 0 && params['state']) { if (params['state'] == localStorage.getItem('state')) { localStorage.setItem('oauth2-test-params', JSON.stringify(params) ); trySampleRequest(); } else { console.log('State mismatch. Possible CSRF attack'); } } // Function to generate a random state value function generateCryptoRandomState() { const randomValues = new Uint32Array(2); window.crypto.getRandomValues(randomValues); // Encode as UTF-8 const utf8Encoder = new TextEncoder(); const utf8Array = utf8Encoder.encode( String.fromCharCode.apply(null, randomValues) ); // Base64 encode the UTF-8 data return btoa(String.fromCharCode.apply(null, utf8Array)) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); } // If there's an access token, try an API request. // Otherwise, start OAuth 2.0 flow. function trySampleRequest() { var params = JSON.parse(localStorage.getItem('oauth2-test-params')); if (params && params['access_token']) { var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://www.googleapis.com/drive/v3/about?fields=user&' + 'access_token=' + params['access_token']); xhr.onreadystatechange = function (e) { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.response); } else if (xhr.readyState === 4 && xhr.status === 401) { // Token invalid, so prompt for user permission. oauth2SignIn(); } }; xhr.send(null); } else { oauth2SignIn(); } } /* * Create form to request access token from Google's OAuth 2.0 server. */ function oauth2SignIn() { // create random state value and store in local storage var state = generateCryptoRandomState(); localStorage.setItem('state', state); // Google's OAuth 2.0 endpoint for requesting an access token var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth'; // Create element to open OAuth 2.0 endpoint in new window. var form = document.createElement('form'); form.setAttribute('method', 'GET'); // Send as a GET request. form.setAttribute('action', oauth2Endpoint); // Parameters to pass to OAuth 2.0 endpoint. var params = {'client_id': YOUR_CLIENT_ID, 'redirect_uri': YOUR_REDIRECT_URI, 'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly', 'state': state, 'include_granted_scopes': 'true', 'response_type': 'token'}; // Add form parameters as hidden input values. for (var p in params) { var input = document.createElement('input'); input.setAttribute('type', 'hidden'); input.setAttribute('name', p); input.setAttribute('value', params[p]); form.appendChild(input); } // Add form to page and submit it to open the OAuth 2.0 endpoint. document.body.appendChild(form); form.submit(); } </script> <button onclick="trySampleRequest();">Try sample request</button> </body></html>
Quy tắc xác thực nguồn gốc JavaScript
Google áp dụng các quy tắc xác thực sau đây đối với nguồn gốc JavaScript để giúp nhà phát triển bảo mật ứng dụng của họ. Các nguồn gốc JavaScript của bạn phải tuân thủ những quy tắc này. Xem phần 3 của RFC 3986 để biết định nghĩa về miền, máy chủ lưu trữ và giao thức nêu dưới đây.
Các quy tắc xác thực | |
---|---|
Lược đồ |
Các nguồn gốc JavaScript phải sử dụng giao thức HTTPS, không phải HTTP thuần tuý. Các URI của máy chủ cục bộ (bao gồm cả URI địa chỉ IP của máy chủ cục bộ) được miễn áp dụng quy tắc này. |
Máy chủ lưu trữ |
Máy chủ lưu trữ không được là địa chỉ IP thô. Địa chỉ IP của máy chủ lưu trữ cục bộ được miễn khỏi quy tắc này. |
Miền |
“googleusercontent.com” .goo.gl ) trừ phi ứng dụng sở hữu miền. |
Thông tin người dùng |
Nguồn gốc JavaScript không được chứa thành phần phụ userinfo. |
Đường dẫn |
Nguồn gốc JavaScript không được chứa thành phần đường dẫn. |
Cụm từ tìm kiếm |
Nguồn gốc JavaScript không được chứa thành phần truy vấn. |
Mảnh |
Nguồn gốc JavaScript không được chứa thành phần mảnh. |
Ký tự |
Nguồn gốc JavaScript không được chứa một số ký tự nhất định, trong đó có:
|
Uỷ quyền gia tăng
Trong giao thức OAuth 2.0, ứng dụng của bạn yêu cầu quyền truy cập vào các tài nguyên được xác định theo phạm vi. Đây được xem là phương pháp hay nhất về trải nghiệm người dùng để yêu cầu uỷ quyền cho các tài nguyên vào thời điểm bạn cần. Để thực hiện điều đó, máy chủ uỷ quyền của Google có hỗ trợ tính năng uỷ quyền gia tăng. Tính năng này cho phép bạn yêu cầu phạm vi khi cần thiết và nếu người dùng cấp quyền cho phạm vi mới, hãy trả về một mã uỷ quyền có thể đổi lấy một mã thông báo chứa tất cả các phạm vi mà người dùng đã cấp cho dự án.
Ví dụ: một ứng dụng cho phép người dùng lấy mẫu các bản nhạc và tạo danh sách kết hợp có thể cần rất ít tài nguyên tại thời điểm đăng nhập, có lẽ không có gì khác ngoài tên của người đăng nhập. Tuy nhiên, để lưu xong danh sách kết hợp, bạn sẽ phải có quyền truy cập vào Google Drive của mình. Hầu hết mọi người sẽ thấy điều đó là bình thường nếu họ chỉ được yêu cầu cấp quyền truy cập vào Google Drive vào thời điểm ứng dụng thực sự cần đến.
Trong trường hợp này, tại thời điểm đăng nhập, ứng dụng có thể yêu cầu phạm vi openid
và profile
để thực hiện hoạt động đăng nhập cơ bản, sau đó yêu cầu phạm vi https://www.googleapis.com/auth/drive.file
tại thời điểm yêu cầu đầu tiên để lưu kết hợp.
Các quy tắc sau áp dụng cho mã truy cập nhận được từ hoạt động uỷ quyền gia tăng:
- Bạn có thể dùng mã thông báo để truy cập vào các tài nguyên tương ứng với bất kỳ phạm vi nào đã được cuộn vào hoạt động uỷ quyền kết hợp mới.
- Khi bạn dùng mã làm mới cho uỷ quyền kết hợp để lấy mã truy cập, mã truy cập này đại diện cho uỷ quyền kết hợp và có thể được dùng cho bất kỳ giá trị
scope
nào có trong phản hồi. - Hoạt động uỷ quyền kết hợp bao gồm tất cả phạm vi mà người dùng đã cấp cho dự án API ngay cả khi các ứng dụng khác yêu cầu cấp quyền. Ví dụ: nếu người dùng cấp quyền truy cập vào một phạm vi bằng ứng dụng dành cho máy tính, sau đó cấp một phạm vi khác cho chính ứng dụng đó thông qua ứng dụng dành cho thiết bị di động, thì việc uỷ quyền kết hợp sẽ bao gồm cả hai phạm vi.
- Nếu bạn thu hồi một mã thông báo đại diện cho một lệnh uỷ quyền kết hợp, thì quyền truy cập vào tất cả phạm vi của quyền đó thay mặt cho người dùng được liên kết sẽ bị thu hồi đồng thời.
Các mã mẫu dưới đây cho biết cách thêm phạm vi vào mã truy cập hiện có. Phương pháp này cho phép ứng dụng của bạn tránh phải quản lý nhiều mã truy cập.
Điểm cuối OAuth 2.0
Để thêm phạm vi vào mã truy cập hiện có, hãy đưa tham số include_granted_scopes
vào yêu cầu của bạn tới máy chủ OAuth 2.0 của Google.
Đoạn mã sau đây minh hoạ cách thực hiện việc đó. Đoạn mã giả định rằng bạn đã lưu trữ các phạm vi mà mã truy cập hợp lệ trong bộ nhớ cục bộ của trình duyệt. (Mã ví dụ đầy đủ lưu trữ danh sách các phạm vi mà mã truy cập hợp lệ bằng cách đặt thuộc tính oauth2-test-params.scope
trong bộ nhớ cục bộ của trình duyệt.)
Đoạn mã này so sánh các phạm vi mà mã truy cập hợp lệ với phạm vi bạn muốn sử dụng cho một truy vấn cụ thể. Nếu mã truy cập không thuộc phạm vi đó, quy trình OAuth 2.0 sẽ bắt đầu.
Ở đây, hàm oauth2SignIn
giống như hàm đã được cung cấp trong bước 2 (và được cung cấp sau trong ví dụ hoàn chỉnh).
var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly'; var params = JSON.parse(localStorage.getItem('oauth2-test-params')); var current_scope_granted = false; if (params.hasOwnProperty('scope')) { var scopes = params['scope'].split(' '); for (var s = 0; s < scopes.length; s++) { if (SCOPE == scopes[s]) { current_scope_granted = true; } } } if (!current_scope_granted) { oauth2SignIn(); // This function is defined elsewhere in this document. } else { // Since you already have access, you can proceed with the API request. }
Thu hồi mã thông báo
Trong một số trường hợp, người dùng có thể muốn thu hồi quyền truy cập đã cấp cho ứng dụng. Người dùng có thể thu hồi quyền truy cập bằng cách truy cập vào phần Cài đặt tài khoản. Hãy xem tài liệu hỗ trợ về Xoá quyền truy cập vào trang web hoặc ứng dụng trong phần Các trang web và ứng dụng của bên thứ ba có quyền truy cập vào tài khoản của bạn để biết thêm thông tin.
Ứng dụng cũng có thể thu hồi quyền truy cập đã cấp cho ứng dụng theo phương thức lập trình. Việc thu hồi có lập trình đóng vai trò quan trọng trong những trường hợp người dùng huỷ đăng ký, xoá ứng dụng hoặc tài nguyên API mà ứng dụng yêu cầu đã thay đổi đáng kể. Nói cách khác, một phần của quy trình xoá có thể bao gồm cả yêu cầu API để đảm bảo các quyền đã cấp trước đó cho ứng dụng sẽ bị xoá.
Điểm cuối OAuth 2.0
Để thu hồi một mã thông báo theo phương thức lập trình, ứng dụng sẽ gửi yêu cầu đến https://oauth2.googleapis.com/revoke
và đưa mã thông báo đó vào dưới dạng một tham số:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
Mã thông báo này có thể là mã truy cập hoặc mã làm mới. Nếu mã thông báo này là mã truy cập và có mã làm mới tương ứng, thì mã làm mới cũng sẽ bị thu hồi.
Nếu yêu cầu thu hồi được xử lý thành công, thì mã trạng thái HTTP của phản hồi sẽ là 200
. Đối với các điều kiện lỗi, hệ thống sẽ trả về mã trạng thái HTTP 400
cùng với mã lỗi.
Đoạn mã JavaScript sau đây cho biết cách thu hồi một mã thông báo trong JavaScript mà không cần sử dụng Thư viện ứng dụng API của Google cho JavaScript. Vì điểm cuối OAuth 2.0 của Google dùng để thu hồi mã thông báo không hỗ trợ tính năng Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS), nên mã này sẽ tạo một biểu mẫu và gửi biểu mẫu đến điểm cuối thay vì sử dụng phương thức XMLHttpRequest()
để đăng yêu cầu.
function revokeAccess(accessToken) { // Google's OAuth 2.0 endpoint for revoking access tokens. var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke'; // Create <form> element to use to POST data to the OAuth 2.0 endpoint. var form = document.createElement('form'); form.setAttribute('method', 'post'); form.setAttribute('action', revokeTokenEndpoint); // Add access token to the form so it is set as value of 'token' parameter. // This corresponds to the sample curl request, where the URL is: // https://oauth2.googleapis.com/revoke?token={token} var tokenField = document.createElement('input'); tokenField.setAttribute('type', 'hidden'); tokenField.setAttribute('name', 'token'); tokenField.setAttribute('value', accessToken); form.appendChild(tokenField); // Add form to page and submit it to actually revoke the token. document.body.appendChild(form); form.submit(); }