簡體   English   中英

Google+登錄,PHP一次性代碼/服務器端流,沒有“Silex / twig”

[英]Google+ sign in, PHP one-time-code/server-side flow without “Silex/twig”

用於服務器端應用的Google+登錄示例代碼

  // Create a state token to prevent request forgery.
  // Store it in the session for later validation.
  $state = md5(rand());
  $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
  ));

在此輸入圖像描述

問題:如何在沒有silex / twig的情況下進行服務器端工作?

有兩個答案,因為有兩個你想要沒有的庫。

對於第一個(Silex):

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = md5(rand());
$app['session']->set('state', $state);

這只是存儲一個會話變量供以后使用。 這可以在PHP中輕松完成:

<?php
session_start();

$state = md5(rand());
$_SESSION['state'] = $state;
?>

稍后,您將通過比較客戶端發送到$_SESSION['state']來驗證來自客戶端的正確狀態值。

第二部分(Twig):

// 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
));

這只是用已知值替換渲染HTML中的值。 您可以通過將示例index.html中的{{ VARIABLE_NAME }}每個實例替換為PHP變量(例如將{{ CLIENT_ID }}更改為<?php echo $CLIENT_ID; ?> )來實現此目的,然后,當然,在代碼中設置該變量。

然后,您將調用您的PHP腳本,並讀入您的腳本並返回index.html文件。

編輯 步驟7:確認服務器上的反請求偽造狀態令牌

// Ensure that this 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);
}

而是使用:

if ($_REQUEST['state'] != $_SESSION['state'])) {
  header("HTTP/1.1 401 Unauthorized");
  echo "Invalid state parameter";
  exit;
}

對於第8步:初始化Google API客戶端庫並啟動Google+服務

對於return new Response('{Message}', {HTTP status code});每一行return new Response('{Message}', {HTTP status code}); 用它替換它

header("HTTP/1.1 {HTTP status code});
echo "{Message}";
exit;

然后而不是

// Store the token in the session for later use.
$app['session']->set('token', json_encode($token));
$response = 'Succesfully connected with token: ' . print_r($token, true);

// Store the token in the session for later use.
$_SESSION['token'] = json_encode($token));
$response = 'Succesfully connected with token: ' . print_r($token, true);

我用這個客戶端庫(PHP)
請測試此代碼,它工作正常
的index.php

<?php
session_start();
$data['state'] = md5(uniqid(rand(), true));
$_SESSION['state'] = $data['state'];
?>
<html itemscope itemtype="http://schema.org/Article">
<head>
  <!-- BEGIN Pre-requisites -->
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
  </script>
  <meta name="google-signin-scope" content="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.moments.write https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.profile.agerange.read https://www.googleapis.com/auth/plus.profile.language.read https://www.googleapis.com/auth/plus.circles.members.read https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/userinfo.email" />

  <script type="text/javascript">
    (function () {
      var po = document.createElement('script');
      po.type = 'text/javascript';
      po.async = true;
      po.src = 'https://plus.google.com/js/client:plusone.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(po, s);
    })();
  </script>
  <!-- END Pre-requisites -->
</head>
<body>
<!-- Add where you want your sign-in button to render -->
<div id="signinButton">
  <span class="g-signin"
    data-scope="https://www.googleapis.com/auth/plus.login"
    data-clientid="Your clientid"
    data-redirecturi="postmessage"
    data-accesstype="offline"
    data-cookiepolicy="single_host_origin"
    data-callback="signInCallback">
  </span>
</div>
<button id="signoutButton" style="display:none" onclick="signout()">signout</button>
<div id="result"></div>

<script type="text/javascript">
function signInCallback(authResult) {
  if (authResult['code']) {
    // Hide the sign-in button now that the user is authorized, for example:
    $('#signinButton').attr('style', 'display: none');
    $('#signoutButton').attr('style', 'display: block');
    var state = '<?php echo $_SESSION['state']; ?>';
    var param = new Array();
    var param = [authResult['code'],state];
    // Send the code to the server
    $.ajax({
      type: 'POST',
      url: 'plus.php?storeToken&state',
      contentType: 'application/octet-stream; charset=utf-8',
      success: function(result) {
        // Handle or verify the server response if necessary.
       console.log(result);
        alert('connected');
      },
      processData: false,
      data: param
    });
  } else if (authResult['error']) {
    alert('Could not automatially log in the user');
     console.log('There was an error: ' + authResult['error']);
  }
}

function signout(){ 
       gapi.auth.signOut();
        $('#signoutButton').attr('style', 'display: none');
        $('#signinButton').attr('style', 'display: block');
        console.log('sign out');
}
</script>
</body>
</html>

plus.php

<?php
session_start();
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_PlusService.php';
  $client = new Google_Client();
  $CLIENT_ID = 'CLIENT ID';
  $client->setClientId($CLIENT_ID);
  $client->setClientSecret('Client Secret');
  $client->setRedirectUri('postmessage');

 $code = explode(",",file_get_contents('php://input'));

  if (isset($code[1]) && $code[1] === $_SESSION['state'])
{
$plus = new Google_PlusService($client);
  $client->authenticate($code[0]);
  $token = json_decode($client->getAccessToken());

  // Verify the token
  $reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' .
          $token->access_token;

  $req = new Google_HttpRequest($reqUrl);

  $tokenInfo = json_decode(
      $client::getIo()->authenticatedRequest($req)->getResponseBody());

  $userId = $tokenInfo->user_id;
  $userEmail = $tokenInfo->email;

  // If there was an error in the token info, abort.
  if (isset($tokenInfo->error)) {
    print $tokenInfo->error;
  } 
  // Make sure the token we got is for our app.
   if ($tokenInfo->audience != $CLIENT_ID) {
    print "Token's client ID does not match app's.";
  }

print 'Token from result: ' . print_r($token, true);
print '<<<<<<<<<<< tokenInfo >>>>>>> ' . print_r($tokenInfo, true);

}
else
{
          echo "Invalid state parameter";
}

不要忘記添加您的CLIENT IDClient Secret
退出不在localhost中工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM