具有 Google 客户端 PHP 身份验证流程的 CSRF
CSRF With Google Client PHP Authentication Flow
我正在集成 Google 使用 Open ID. The documentation says that I need to create an anti-forgery state token. I have read several references about CSRF (Sitepoint, Whosebug, Shiflett 登录)和其他几个。我无法完全理解我应该如何实施此解决方案。
我很确定我没有正确理解这个概念,但我正在努力。这是我到目前为止编写的过程:
<?php session_start();
//INCLUDE PHP CLIENT LIBRARY
require_once 'vendor/autoload.php';
$scopes = array('email', 'profile');
// Create client object
$client = new Google_Client();
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/index.php');
$client->setAuthConfig("client.json");
$client->addScope($scopes);
$client->setAccessType("offline");
if( isset($_SESSION["access_token"]) && $_SESSION["access_token"]) {
if(isset($_SESSION['tokencsrf']) && $_SESSION['tokencsrf'] !== "") {
$client->setAccessToken($_SESSION["access_token"]);
if ($client->isAccessTokenExpired()) {
$refreshTokenTxt = "refreshToken.txt";
$tokenHandle = fopen($refreshTokenTxt, "r");
$refreshToken = fread($tokenHandle, filesize($refreshTokenTxt));
$client->refreshToken($refreshToken);
$_SESSION['access_token'] = $client->getAccessToken();
$client->setAccessToken($_SESSION["access_token"]);
}
$objOAuthService = new Google_Service_Oauth2($client);
$userData = $objOAuthService->userinfo->get();
var_dump($userData);
} else {
die(" --- INVALID CSRF! ---");
}
} else {
$_SESSION['tokencsrf'] = bin2hex(openssl_random_pseudo_bytes(16));
if( !isset($_GET["code"]) ){
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$refreshTokenTxt = "refreshToken.txt";
if (!file_exists($refreshTokenTxt)) {
$tokenHandle = fopen($refreshTokenTxt, "w");
fwrite($tokenHandle, $_SESSION['access_token']["refresh_token"]);
}
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/index.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
}
?>
当然,这是一个测试脚本,看看这样做是否正确。到目前为止效果很好,但我不确定这是否是正确的方法。我恳请某人提供支持,以确认这是否可以使用或可以提出哪些更改建议。非常感谢您的宝贵意见!
我现在为自己感到羞愧。文档非常清楚,但我的想法不是。 CSRF 是通过将 "state" 参数传递给客户端对象来实现的。
$state = bin2hex(openssl_random_pseudo_bytes(16));
$_SESSION["state"] = $state;
// Create client object
$client = new Google_Client();
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/index.php');
$client->setAuthConfig("client.json");
$client->addScope($scopes);
$client->setAccessType("offline");
$client->setState($state);
然后,认证完成后,只要确认返回的token与session中的一致即可。
if( $_GET["state"] == $_SESSION["state"]) {
//do stuff here...
}
我正在集成 Google 使用 Open ID. The documentation says that I need to create an anti-forgery state token. I have read several references about CSRF (Sitepoint, Whosebug, Shiflett 登录)和其他几个。我无法完全理解我应该如何实施此解决方案。
我很确定我没有正确理解这个概念,但我正在努力。这是我到目前为止编写的过程:
<?php session_start();
//INCLUDE PHP CLIENT LIBRARY
require_once 'vendor/autoload.php';
$scopes = array('email', 'profile');
// Create client object
$client = new Google_Client();
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/index.php');
$client->setAuthConfig("client.json");
$client->addScope($scopes);
$client->setAccessType("offline");
if( isset($_SESSION["access_token"]) && $_SESSION["access_token"]) {
if(isset($_SESSION['tokencsrf']) && $_SESSION['tokencsrf'] !== "") {
$client->setAccessToken($_SESSION["access_token"]);
if ($client->isAccessTokenExpired()) {
$refreshTokenTxt = "refreshToken.txt";
$tokenHandle = fopen($refreshTokenTxt, "r");
$refreshToken = fread($tokenHandle, filesize($refreshTokenTxt));
$client->refreshToken($refreshToken);
$_SESSION['access_token'] = $client->getAccessToken();
$client->setAccessToken($_SESSION["access_token"]);
}
$objOAuthService = new Google_Service_Oauth2($client);
$userData = $objOAuthService->userinfo->get();
var_dump($userData);
} else {
die(" --- INVALID CSRF! ---");
}
} else {
$_SESSION['tokencsrf'] = bin2hex(openssl_random_pseudo_bytes(16));
if( !isset($_GET["code"]) ){
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$refreshTokenTxt = "refreshToken.txt";
if (!file_exists($refreshTokenTxt)) {
$tokenHandle = fopen($refreshTokenTxt, "w");
fwrite($tokenHandle, $_SESSION['access_token']["refresh_token"]);
}
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/index.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
}
?>
当然,这是一个测试脚本,看看这样做是否正确。到目前为止效果很好,但我不确定这是否是正确的方法。我恳请某人提供支持,以确认这是否可以使用或可以提出哪些更改建议。非常感谢您的宝贵意见!
我现在为自己感到羞愧。文档非常清楚,但我的想法不是。 CSRF 是通过将 "state" 参数传递给客户端对象来实现的。
$state = bin2hex(openssl_random_pseudo_bytes(16));
$_SESSION["state"] = $state;
// Create client object
$client = new Google_Client();
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/index.php');
$client->setAuthConfig("client.json");
$client->addScope($scopes);
$client->setAccessType("offline");
$client->setState($state);
然后,认证完成后,只要确认返回的token与session中的一致即可。
if( $_GET["state"] == $_SESSION["state"]) {
//do stuff here...
}