2017-06-06 111 views
0

我在创建用于Google Drive授权的JWT时遇到问题。 该指令在this link中给出。Google Drive Auth:从JSON版私钥中创建JWT签名

<?php 
//helper function 
function base64url_encode($data) { 
return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
} 

//Google's Documentation of Creating a JWT https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests 

$raw_key_data="-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkWhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCLJN7B2USp0bTH\n7aVt1K/pAJa9rgUEkebbRQUPEopManZHgJK8SMzq5nUM3OOVlTdyDyuzxUZW65Y+\nR1xajNHSidE+rJJ3MWwuevXBuUws5oiA+DXJBB6FsTtHDvUPT7sePbJx8Y80S1Jr\nB3apJNdohjSef4UihgjJ93A0PgeSVz7CeUKxrBHdGiK2Ikf7wTCzcRzz/15I6QLu\ncsNbWxo0+koXo9D0+wT3RN+riSyTa2WwYn//B8v6VmDPVrcjxETEXraAIMpqURtK\n4BuK4Qp2pSd1u2zrGc58BVGuT6+nPVpmX6wiZ21sqOulTzgIOXKIuc4zdKvZ+jz/\n1jst3ertAgMBAAECggEADRGn+IYbLGYdeD/Kb2/wG87p2aP8Jas8hzDK4lkH81h2\nho29eoDN+mwt50jh+V08CXMCVE69phFXmb7jHkAmvwMhy6Sy1w4lzpHO/mSUko0O\nmip2BszjvwPgAPMXMlp3RUZfOdOJ80v10Eaxrv5eWxtr2s04aH81WR7sA4Ql+uki\nbTiLbo4odpMVPkoJZATZKQd+L/bBM4a+b3IM87/TE7skMrSgQE6cnjjTI5Uk+WSl\nxjiZvj5XmticW3vPavL/ZXPEZqy5IxvcxdF5rGHCHVu4ah0CmDdc9A3jF0flhewK\nV6mOViqbKGInnMn4kt3l4C3+wF2+dge6t8BQ/TMtwwKBgQDBnpjiC+wRVQy36KCs\ntYdZ60ykuQeKqMyACt6FvC74xy+PjLVntxDaYArva2PVaZSm9B2FgGHPz9AfW80/\n1ZeNHcuwymni8n+4MNpQbJuhuHK8UjSo0rFq6Nrddi9RCjzASSX8s4Dlm01VM65b\nKBnM5p50I9QEY4F4gSZfLLMNowKBgQC3+Tpz23qhkxJPu9cVuvPRFfg1y0NNsp7k\n0qHYMegz1GHoMVs1kg36OtbROqpG2+rIrj0JWTGwLO14fX2TY0jWfao21CGrpkXM\nlY1KSDIMuQv6pd5yh74oqvDDpZwKxxu/nmzcQbd1lN/nFkEW5g0b7e27UoCoovwS\n7qSENbqOLwKBgHYWp8H+aX1stPQZ8p1DngiupTE2FK5yIz/Y4T0JuFBNE+nmdOGL\n2sCFoUXC5sHLwjlNXBAHbCCV66akk/th5yvPR2NNIOWk51bMnOo+Q3GQEJJhRPLO\nhhzhZlN5+IPhzYmtU3jbdjsTzEex3J6GR64b3fqRu4bttZJsmp2jopUnAoGAWW+7\nzt7/+tR4rnJu2Y2NQjQf+mbaTUddb2kWbPe2Hpw9DJgR8zURvngkPor6hIAc33p1\nCbpmwXLV7yFyjthRbJSizwzJYZzvicmaamY2jqDXBf7k6WC8PSD88t/rwAGTp8/o\ntBruiSbawoi7E9q6vL0qOUqeaVzylnGVYQCNtNkCgYBwqL1MNTR8IrXDfZyYdDRP\nWNCRqm7ymuQi7IUKVa+yaBM1ubvEe7EPrlZWlFPDdPmaScx02Qwf++xcGHWzzDX0\nQPmd95OTGafvECXuKVy2NAf2AdCYVruL+17wfPhuz7ANIpgEqsiNAZNe0GtGBjyZ\nVuiSVVML3jW4XUtf63V0/A==\n-----END PRIVATE KEY-----\n"; 

$private_key = openssl_get_privatekey($raw_key_data); 
if ($private_key === FALSE) 
{ 
    error_log ("Unable to extract private key from raw key data: " . openssl_error_string()); 
}; 

print("$private_key\n"); 

//{Base64url encoded JSON header} 

$jwtHeader = base64url_encode(json_encode(array(
"alg" => "RS256", 
"typ" => "JWT" 
))); 

//{Base64url encoded JSON claim set} 
$now = time(); 
$jwtClaim = base64url_encode(json_encode(array(
"iss" => "[email protected]", 
"scope" => "https://www.googleapis.com/auth/drive.file", 
"aud" => "https://www.googleapis.com/oauth2/v4/token", 
"exp" => $now + 3600, 
"iat" => $now 
))); 

//The base string for the signature: {Base64url encoded JSON header}. {Base64url encoded JSON claim set} 

openssl_sign(
$jwtHeader.".".$jwtClaim, 
$jwtSig, 
$private_key, 
"SHA256" 
); 

$jwtSign = base64url_encode($jwtSig); 

//{Base64url encoded JSON header}.{Base64url encoded JSON claim set}. {Base64url encoded signature} 
$jwtAssertion = $jwtHeader.".".$jwtClaim.".".$jwtSig; 
print("$jwtAssertion\n"); 

?> 

当我运行这个代码时,我得到后面跟着一个无意义的签名。我甚至尝试将私钥放在一个文件中,并从其中有多行的文件中读取(私钥分开在\n),但没有成功。我无法从私钥生成有意义的JWT签名。任何人都可以帮我解决这个问题吗?

谢谢,

回答

1

我设法解决了这个问题。下面是更新后的代码读取从谷歌下载的JSON文件,并创建一个assertion有哪一个可以再从谷歌获得访问令牌:

<?php 
//helper function 
function base64url_encode($data) { 
return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
} 

// Read the JSON credential file my-private-key.json download from Google 
$private_key_file="my-private-key.json"; 
$json_file = file_get_contents($private_key_file); 

$info = json_decode($json_file); 
$private_key = $info->{'private_key'}; 

//{Base64url encoded JSON header} 
$jwtHeader = base64url_encode(json_encode(array(
"alg" => "RS256", 
"typ" => "JWT" 
))); 

//{Base64url encoded JSON claim set} 
$now = time(); 
$jwtClaim = base64url_encode(json_encode(array(
"iss" => $info->{'client_email'}, 
"scope" => "https://www.googleapis.com/auth/drive.file", 
"aud" => "https://www.googleapis.com/oauth2/v4/token", 
"exp" => $now + 3600, 
"iat" => $now 
))); 

$data = $jwtHeader.".".$jwtClaim; 

// Signature 
$Sig = ''; 
openssl_sign($data,$Sig,$private_key,'SHA256'); 
$jwtSign = base64url_encode($Sig ); 


//{Base64url encoded JSON header}.{Base64url encoded JSON claim set}.{Base64url encoded signature} 

$jwtAssertion = $data.".".$jwtSign; 
echo "$jwtAssertion\n"; 

然后,您可以通过与谷歌驱动器进行通信,例如测试代码:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=YOUR-JWT-ASSERTION-BUILD-ABOVE' https://www.googleapis.com/oauth2/v4/token 
+0

它为我工作。谢谢。 –