如何在没有REST API用户身份验证的情况下显示LinkedIn公司的更新?

Currently I am working on a website for a company that wants to show their (company) LinkedIn updates on a webpage. In my opinion, this should be possible to do without the need to login for the viewer (oAuth), however, I can't find a working solution.

I've googled quite a lot and read the documentation quite thoroughly, but could not find a satisfying answer. Therefore, I come to you.

Current Case

Without oAuth authorization a 504 Gateway error appears, otherwise the viewer is required to login to LinkedIn to view the company updates. Another weird thing is that a few weeks ago, the API worked fine: the company updates showed without the need to login for the viewer, did anyone else experience this?

Questions

  • Is it possible to show (your own) companies updates on a webpage without the need to login (for the viewer)?
  • If so, could you show me an example with LinkedIn's own updates? Because the documentation does not make much sense on this point.

  • [just to confirm] Did anyone else experience a change in the need for authorization of the LinkedIn API?

A small first-version API wrapper that I created for this purpose:

<?php
class Linkedin{

const API_LINK  = 'https://api.linkedin.com/v1/';                           // Link to API
const AUTH_LINK = 'https://www.linkedin.com/uas/oauth2/authorization?';     // Authorisation link
const ACC_LINK  = 'https://www.linkedin.com/uas/oauth2/accessToken?';       // Access token link

private $sApikey;
private $sApisecret;
private $sState;
private $sScope;
private $sRedirectUri;
private $aErrors = array();

public function __construct($aParams = array()){
    /* Check input */
    if(count($aParams)<1){
        logmsg('There where no parameters given to the linkedin api.');
        return false;
    }

    /* Basic settings */
    $aSettings = array(
        'api_key'            => null,
        'api_secret'         => null,
        'scope'              => 'r_basicprofile',
        'redirect_uri'       => 'http://' . $_SERVER['SERVER_NAME']
    );
    $aSettings = array_merge($aSettings,$aParams);

    /* Set variables */
    $this->sApikey      = $aSettings['api_key'];
    $this->sApisecret   = $aSettings['api_secret'];
    $this->sScope       = $aSettings['scope'];
    $this->sRedirectUri = $aSettings['redirect_uri'];
}



public function company($iCompanyID, $aSettings = array()){

    $aOutput = $this->fetch('GET', 'companies/'.$iCompanyID.'/updates', $aSettings);

    logmsg($aOutput);
    return $aOutput;
}


public function getErrors($sType = 'array'){
    switch($sType){
        case 'html':
            $sOutput = '<div class="error">';
            $sOutput.= '<p>The LinkedIn API failed to connect due to the following error(s):</p>';
            $sOutput.= '<ul>';
            foreach($this->aErrors as $i => $sError){
                $sOutput.= '<li>'.$sError.'</li>';
            }
            $sOutput.= '</ul></div>';
            return $sOutput;
        case 'array':
        default: 
            return $this->aErrors;
    }
}
private function setError($sString){
    $this->aErrors[] = $sString;
}



/* The actual fetch */
private function fetch($sMethod, $sLink, $aParams = array()) {

    if($_SESSION['access_code']){
        $aHeaders = array(
            'Authorization' => 'Bearer ' . $_SESSION['access_token'],
            'x-li-format' => 'json', // Comment out to use XML
        );
    }

    // Need to use HTTPS
    $sUrl = trim(self::API_LINK,'/').'/' . trim($sLink,'/');

    // Append query parameters (if there are any)
    if (count($aParams)) { 
        $sUrl .= '?' . http_build_query($aParams); 
    } 

    // Tell streams to make a (GET, POST, PUT, or DELETE) request
    // And use OAuth 2 access token as Authorization
    $context = stream_context_create(
        array('http' => 
              array('method' => $sMethod,
                    'header' => (isset($aHeaders)) ? $aHeaders : null
                   )
             )
    );

    // Hocus Pocus
    $sResponse = file_get_contents($sUrl, false, $context);

    // Native PHP object, please
    return json_decode($sResponse);
}

/* Authorisation handler */
public function oAuth(){
    // OAuth 2 Control Flow
    if (isset($_GET['error'])) {
        $this->setError(trim(htmlentities($_GET['error'].': '.$_GET['error_description'])));
        return false;
    } elseif (isset($_GET['code'])) {
        // User authorized your application
        if ($this->getState() == $_GET['state']) {
            // Get token so you can make API calls
            if($this-getAccessToken()){
                return true;   
            }
        } else {
            logmsg('Possible CRFS attack. Wrong state code: "'.$this->getState() .'" != "'.$_GET['state'].'"',2);
            $this->setError('Login to Linkedin failed because an attack was detected.');
            return false;
        }
    } else { 
        if ((empty($_SESSION['expires_at'])) || (time() > $_SESSION['expires_at'])) {
            // Token has expired, clear the state
            $_SESSION = array();
        }
        if (!isset($_SESSION['access_token']) || empty($_SESSION['access_token'])) {
            // Start authorization process
            $this->getAuthorisation();
        }
    }
}

/* Get Authorisation code */
private function getAuthorisation(){
    $aParams = array(
        'response_type' => 'code',
        'client_id' => $this->sApikey,
        'scope' => $this->sScope,
        'state' => $this->getState(),
        'redirect_uri' => $this->sRedirectUri,
    );

    // Authentication request
    $sUrl = self::AUTH_LINK . http_build_query($aParams);

    // Redirect user to authenticate
    header("Location: $sUrl");
    exit();  
}

/* Get access token */
private function getAccessToken(){
    $aParams = array(
        'grant_type' => 'authorization_code',
        'client_id' => $this->sApikey,
        'client_secret' => $this->sApisecret,
        'code' => $_GET['code'],
        'redirect_uri' => $this->sRedirectUri,
    );

    // Access Token request
    $sUrl = self::ACC_LINK . http_build_query($aParams);

    // Tell streams to make a POST request
    $sContext = stream_context_create(
        array('http' => array('method' => 'POST') )
    );

    // Retrieve access token information
    $sResponse = file_get_contents($sUrl, false, $sContext);

    // Native PHP object, please
    $oToken = json_decode($sResponse);

    // Store access token and expiration time
    $_SESSION['access_token'] = $oToken->access_token; // guard this! 
    $_SESSION['expires_in']   = $oToken->expires_in; // relative time (in seconds)
    $_SESSION['expires_at']   = time() + $_SESSION['expires_in']; // absolute time

    return true;
}


private function getState(){
    if(is_null($this->sScope)){
        if(!isset($_SESSION['ln-api-scope'])){
            $_SESSION['ln-api-scope'] = md5(uniqid(rand(), true));
        }
        $this->sScope = $_SESSION['ln-api-scope'];
    }
    return $this->sScope;
}

}

With the scope set to rw_nus and the API key and secret supplied.

Thanks for any help in advance.

With kind regards,

fps