Nếu bạn chỉ muốn tìm nạp id người dùng Google, tên và hình ảnh cho khách truy cập vào ứng dụng web của bạn - đây là giải pháp bên dịch vụ PHP thuần túy của tôi cho năm 2020 mà không sử dụng thư viện bên ngoài -
Nếu bạn đọc hướng dẫn Sử dụng OAuth 2.0 cho Ứng dụng Máy chủ Web của Google (và hãy cẩn thận, Google thích thay đổi các liên kết đến tài liệu của riêng mình), thì bạn chỉ phải thực hiện 2 bước:
- Đưa cho khách truy cập một trang web yêu cầu đồng ý chia sẻ tên của họ với ứng dụng web của bạn
- Sau đó, lấy "mã" do trang web trên chuyển đến ứng dụng web của bạn và tìm nạp mã thông báo (thực tế là 2) từ Google.
Một trong những mã thông báo được trả lại được gọi là "id_token" và chứa id người dùng, tên và ảnh của khách truy cập.
Đây là mã PHP của một trò chơi trên web của tôi. Ban đầu, tôi đang sử dụng SDK Javascript, nhưng sau đó tôi nhận thấy rằng dữ liệu người dùng giả mạo có thể được chuyển đến trò chơi trên web của tôi, khi chỉ sử dụng SDK phía máy khách (đặc biệt là id người dùng, điều quan trọng đối với trò chơi của tôi), vì vậy tôi đã chuyển sang sử dụng PHP ở phía máy chủ:
<?php
const APP_ID = '1234567890-abcdefghijklmnop.apps.googleusercontent.com';
const APP_SECRET = 'abcdefghijklmnopq';
const REDIRECT_URI = 'https://the/url/of/this/PHP/script/';
const LOCATION = 'Location: https://accounts.google.com/o/oauth2/v2/auth?';
const TOKEN_URL = 'https://oauth2.googleapis.com/token';
const ERROR = 'error';
const CODE = 'code';
const STATE = 'state';
const ID_TOKEN = 'id_token';
# use a "random" string based on the current date as protection against CSRF
$CSRF_PROTECTION = md5(date('m.d.y'));
if (isset($_REQUEST[ERROR]) && $_REQUEST[ERROR]) {
exit($_REQUEST[ERROR]);
}
if (isset($_REQUEST[CODE]) && $_REQUEST[CODE] && $CSRF_PROTECTION == $_REQUEST[STATE]) {
$tokenRequest = [
'code' => $_REQUEST[CODE],
'client_id' => APP_ID,
'client_secret' => APP_SECRET,
'redirect_uri' => REDIRECT_URI,
'grant_type' => 'authorization_code',
];
$postContext = stream_context_create([
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($tokenRequest)
]
]);
# Step #2: send POST request to token URL and decode the returned JWT id_token
$tokenResult = json_decode(file_get_contents(TOKEN_URL, false, $postContext), true);
error_log(print_r($tokenResult, true));
$id_token = $tokenResult[ID_TOKEN];
# Beware - the following code does not verify the JWT signature!
$userResult = json_decode(base64_decode(str_replace('_', '/', str_replace('-', '+', explode('.', $id_token)[1]))), true);
$user_id = $userResult['sub'];
$given_name = $userResult['given_name'];
$family_name = $userResult['family_name'];
$photo = $userResult['picture'];
if ($user_id != NULL && $given_name != NULL) {
# print your web app or game here, based on $user_id etc.
exit();
}
}
$userConsent = [
'client_id' => APP_ID,
'redirect_uri' => REDIRECT_URI,
'response_type' => 'code',
'scope' => 'profile',
'state' => $CSRF_PROTECTION,
];
# Step #1: redirect user to a the Google page asking for user consent
header(LOCATION . http_build_query($userConsent));
?>
Bạn có thể sử dụng thư viện PHP để thêm bảo mật bằng cách xác minh chữ ký JWT. Đối với mục đích của tôi, điều đó là không cần thiết, bởi vì tôi tin tưởng rằng Google sẽ không phản bội trò chơi web nhỏ của tôi bằng cách gửi dữ liệu khách truy cập giả mạo.
Ngoài ra, nếu bạn muốn lấy thêm dữ liệu cá nhân của khách truy cập, thì bạn cần bước thứ ba:
const USER_INFO = 'https://www.googleapis.com/oauth2/v3/userinfo?access_token=';
const ACCESS_TOKEN = 'access_token';
# Step #3: send GET request to user info URL
$access_token = $tokenResult[ACCESS_TOKEN];
$userResult = json_decode(file_get_contents(USER_INFO . $access_token), true);
Hoặc bạn có thể nhận được nhiều quyền hơn thay mặt cho người dùng - xem danh sách dài tại tài liệu Phạm vi OAuth 2.0 cho Google APIs .
Cuối cùng, các hằng số APP_ID và APP_SECRET được sử dụng trong mã của tôi - bạn lấy nó từ bảng điều khiển API của Google :