使用 PHP 从 OAuth REST API 获取 LinkedIn 个人资料
Posted
技术标签:
【中文标题】使用 PHP 从 OAuth REST API 获取 LinkedIn 个人资料【英文标题】:Get LinkedIn profile from OAuth REST API with PHP 【发布时间】:2015-05-12 12:45:35 【问题描述】:我用过这个网站:http://blog.thewebcafes.com/post/1502524959/php-step-by-step-oauth-for-dummies-based-on
创建以下php页面:
<?php
if(!isset($_SESSION))session_start();
define('LINKEDIN_KEY', '**************');
define('LINKEDIN_SECRET', '****************');
//Prepare The Links
$links = array(
'request_token'=>'https://api.linkedin.com/uas/oauth/requestToken',
'authorize'=>'https://www.linkedin.com/uas/oauth/authorize',
'access_token'=>'https://api.linkedin.com/uas/oauth/accessToken'
);
//Validate Parameters Passed Back by LinkedIn
if(isset($_GET['oauth_token']) && isset($_GET['oauth_verifier']) && $_GET['oauth_token']==$_SESSION['linkedin_oauth_token'])
//we have user permission, let's get a token
getAccessToken();
getProfile();
else
//we don't have an authed user yet, let's ask for permission
authUser();
function urlencode_oauth($str)
return str_replace('+',' ',str_replace('%7E','~',rawurlencode($str)));
function getProfile()
global $links;
//Prepare OAuth Parameters
$params = array(
'oauth_consumer_key'=>LINKEDIN_KEY,
'oauth_nonce'=>sha1(microtime()),
'oauth_signature_method'=>'HMAC-SHA1',
'oauth_timestamp'=>time(),
'oauth_token'=>$_SESSION['linkedin_access_token'],
'oauth_version'=>'1.0'
);
//Prepare The Base String
// sort parameters according to ascending order of key
ksort($params);
// prepare URL-encoded query string
$q = array();
foreach ($params as $key=>$value)
$q[] = urlencode_oauth($key).'='.urlencode_oauth($value);
$q = implode('&',$q);
// generate the base string for signature
$parts = array(
'GET',
urlencode_oauth('https://api.linkedin.com/v1/people/~:(id,num-connections,picture-url)?format=json'),
urlencode_oauth($q)
);
$base_string = implode('&',$parts);
//Get The Signature
$key = urlencode_oauth(LINKEDIN_SECRET) . '&' . urlencode_oauth($_SESSION['linkedin_access_token_secret']);
$signature = base64_encode(hash_hmac('sha1',$base_string,$key,true));
//Put the Signature into Parameters and Prepare Authorization Header
$params['oauth_signature'] = $signature;
$str = array();
foreach ($params as $key=>$value)
$str[] = $key . '="'.urlencode_oauth($value).'"';
$str = implode(', ',$str);
$headers = array(
'GET /v1/people/~ HTTP/1.1',
'Host: api.linkedin.com',
'Authorization: OAuth '.$str,
'Connection: Keep-Alive',
'Content-Type: application/json',
'x-li-format: json'
);
//Send GET Request To LinkedIn
$fp = fsockopen("ssl://api.linkedin.com",443,$errno,$errstr,30);
if(!$fp) echo 'Unable to connect to LinkedIn'; exit();
$out = implode("\r\n",$headers)."\r\n\r\n".$xml . "\r\n\r\n";
fputs($fp,$out);
// getting LinkedIn server response
$res = '';
while (!feof($fp)) $res .= fgets($fp,4096);
fclose($fp);
echo 'RESPONSE: ' . $res;
//Make sure the GET is successful
$parts = explode("\n\n",str_replace("\r","",$res));
$headers = explode("\n",$parts[0]);
if ($headers[0] != 'HTTP/1.1 201 Created') echo 'Failed';
function getAccessToken()
global $links;
//Prepare OAuth Parameters
$params = array(
'oauth_consumer_key'=>LINKEDIN_KEY,
'oauth_nonce'=>sha1(microtime()),
'oauth_signature_method'=>'HMAC-SHA1',
'oauth_timestamp'=>time(),
'oauth_token'=>$_GET['oauth_token'],
'oauth_verifier'=>$_GET['oauth_verifier'],
'oauth_version'=>'1.0'
);
//Prepare The Base String
// sort parameters according to ascending order of key
ksort($params);
// prepare URL-encoded query string
$q = array();
foreach ($params as $key=>$value)
$q[] = urlencode_oauth($key).'='.urlencode_oauth($value);
$q = implode('&',$q);
// generate the base string for signature
$parts = array(
'POST',
urlencode_oauth($links['access_token']),
urlencode_oauth($q)
);
$base_string = implode('&',$parts);
//Get The Signature
$key = urlencode_oauth(LINKEDIN_SECRET) . '&' . urlencode_oauth($_SESSION['linkedin_oauth_token_secret']);
$signature = base64_encode(hash_hmac('sha1',$base_string,$key,true));
//Put the Signature into Parameters and Prepare Authorization Header
$params['oauth_signature'] = $signature;
$str = array();
foreach ($params as $key=>$value)
$str[] = $key . '="'.urlencode_oauth($value).'"';
$str = implode(', ',$str);
$headers = array(
'POST /uas/oauth/accessToken HTTP/1.1',
'Host: api.linkedin.com',
'Authorization: OAuth '.$str,
'Content-Type: text/xml;charset=UTF-8',
'Content-Length: 0',
'Connection: close'
);
//Send POST Request To LinkedIn
$fp = fsockopen("ssl://api.linkedin.com",443,$errno,$errstr,30);
if (!$fp) echo 'Unable to connect to LinkedIn'; exit();
$out = implode("\r\n",$headers) . "\r\n\r\n";
fputs($fp,$out);
// getting LinkedIn server response
$res = '';
while (!feof($fp)) $res .= fgets($fp,4096);
fclose($fp);
//Parse the Response to Get The Access Token and Secret
$parts = explode("\n\n",str_replace("\r",'',$res));
$res_headers = explode("\n",$parts[0]);
if ($res_headers[0] != 'HTTP/1.1 200 OK')
echo 'Error getting access token and secret.'; exit();
parse_str($parts[1],$data);
if (empty($data['oauth_token']))
echo 'Failed to get LinkedIn access token.'; exit();
//Save the Request Token and Secret
$_SESSION['linkedin_access_token'] = $data['oauth_token'];
$_SESSION['linkedin_access_token_secret'] = $data['oauth_token_secret'];
// unset the Request Token (not needed anymore)
unset($_SESSION['linkedin_oauth_token']);
unset($_SESSION['linkedin_oauth_token_secret']);
function authUser()
global $links;
//Prepare OAuth Parameters
$params = array(
'oauth_callback'=>"https://sxsw.ampthealth.com/linkedin_callback.php",
'oauth_consumer_key'=>LINKEDIN_KEY,
'oauth_nonce'=>sha1(microtime()),
'oauth_signature_method'=>'HMAC-SHA1',
'oauth_timestamp'=>time(),
'oauth_version'=>'1.0'
);
//Prepare The Base String
// sort parameters according to ascending order of key
ksort($params);
// prepare URL-encoded query string
$q = array();
foreach ($params as $key=>$value)
$q[] = urlencode_oauth($key).'='.urlencode_oauth($value);
$q = implode('&',$q);
// generate the base string for signature
$parts = array(
'POST',
urlencode_oauth($links['request_token']),
urlencode_oauth($q)
);
$base_string = implode('&',$parts);
//Get The Signature
$key = urlencode_oauth(LINKEDIN_SECRET) . '&';
$signature = base64_encode(hash_hmac('sha1',$base_string,$key,true));
//Put the Signature into Parameters and Prepare Authorization Header
$params['oauth_signature'] = $signature;
$str = array();
foreach ($params as $key=>$value)
$str[] = $key . '="'.urlencode_oauth($value).'"';
$str = implode(', ',$str);
$headers = array(
'POST /uas/oauth/requestToken HTTP/1.1',
'Host: api.linkedin.com',
'Authorization: OAuth '.$str,
'Content-Type: text/xml;charset=UTF-8',
'Content-Length: 0',
'Connection: close'
);
//Send POST Request To LinkedIn
$fp = fsockopen("ssl://api.linkedin.com",443,$errno,$errstr,30);
if (!$fp) echo 'Unable to connect to LinkedIn'; exit();
$out = implode("\r\n",$headers) . "\r\n\r\n";
fputs($fp,$out);
// getting LinkedIn server response
$res = '';
while (!feof($fp)) $res .= fgets($fp,4096);
fclose($fp);
//Parse the Response to Get OAuth Token and Secret
$parts = explode("\n\n",str_replace("\r",'',$res));
$res_headers = explode("\n",$parts[0]);
if ($res_headers[0] != 'HTTP/1.1 200 OK')
echo 'Error getting OAuth token and secret.'; exit();
parse_str($parts[1],$data);
if (empty($data['oauth_token']))
echo 'Failed to get LinkedIn request token.'; exit();
//Save the Request Token and Secret
$_SESSION['linkedin_oauth_token'] = $data['oauth_token'];
$_SESSION['linkedin_oauth_token_secret'] = $data['oauth_token_secret'];
//Redirect your user to LinkedIn with the request token
header('Location: '.$links['authorize'].'?oauth_token='.urlencode($data['oauth_token']));
exit();
?>
我能够让用户授权并请求访问令牌,但是在获取基本配置文件时,我收到一个错误:401 Unauthorized Server。我的 getProfile 函数一定有问题,但我对我缺少的东西有点迷茫。
【问题讨论】:
【参考方案1】:您必须按照linkedin 文档here 中的步骤操作。
特别要阅读申请被批准这一点。
【讨论】:
我熟悉此文档,并认为自己处于第 4 步而不是第 2 步。很可能是我的代码存在问题,而且我与 LinkedIn 的连接也存在问题。以上是关于使用 PHP 从 OAuth REST API 获取 LinkedIn 个人资料的主要内容,如果未能解决你的问题,请参考以下文章
OAuth、PHP、Rest API 和 curl 给出 400 Bad Request
Magento 使用 OAuth 通过 REST API 到 NodeJS
REST API 的安全认证,从 OAuth 2.0 到 JWT 令牌
需要使用 Keycloak 和 oAuth2 保护普通 Spring REST API 的示例