0
votes

I'm currently trying to develop a connection to the Reddit api through Oauth using Guzzle. I get to the point where I authenticate in Reddit, then I get to the authorization token, but I can't take the access token from the Guzzle response so I can set it as a cookie and using on subsequent requests. My current code looks like this:

public function __construct(){

    if(isset($_COOKIE['reddit_token'])){
        $token_info = explode(":", $_COOKIE['reddit_token']); 
        $this->token_type = $token_info[0];
        $this->access_token = $token_info[1];
    } else { 
        if (isset($_GET['code'])){
            //capture code from auth
            $code = $_GET["code"];

            //construct POST object for access token fetch request
            $postvals = sprintf("code=%s&redirect_uri=%s&grant_type=authorization_code",
                                $code,
                                redditConfig::$ENDPOINT_OAUTH_REDIRECT);

            //get JSON access token object (with refresh_token parameter)

            $token = self::runCurl(redditConfig::$ENDPOINT_OAUTH_TOKEN, $postvals, null, true);

            //store token and type
            if (isset($token->access_token)){
                $this->access_token = $token->access_token;
                $this->token_type = $token->token_type;

                //set token cookie for later use
                $cookie_time = 60 * 59 + time();  //seconds * minutes = 59 minutes (token expires in 1hr) 
                setcookie('reddit_token', "{$this->token_type}:{$this->access_token}", $cookie_time); 
            }
        } else {
            $state = rand();
            $urlAuth = sprintf("%s?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&state=%s",
                               redditConfig::$ENDPOINT_OAUTH_AUTHORIZE,
                               redditConfig::$CLIENT_ID,
                               redditConfig::$ENDPOINT_OAUTH_REDIRECT,
                               redditConfig::$SCOPES,
                               $state);

            //forward user to PayPal auth page
            header("Location: $urlAuth");
        }
    }

This is my authentication flow. The I have the runCurl method that is going to make the guzzle requests:

private function runCurl($url, $postVals = null, $headers = null, $auth = false){

    $options = array(
        'timeout' => 10,
        'verify' => false,
        'headers' => ['User-Agent' => 'testing/1.0']
    );

    $requestType = 'GET';

    if ($postVals != null){
        $options['body'] = $postVals;
        $requestType = "POST";
    }

    if ($this->auth_mode == 'oauth'){
        $options['headers'] = [
            'User-Agent' => 'testing/1.0',
            'Authorization' => "{$this->token_type} {$this->access_token}"];

    }

    if ($auth){
        $options['auth'] = [redditConfig::$CLIENT_ID, redditConfig::$CLIENT_SECRET];

    }

    $client = new \GuzzleHttp\Client();    
    $response = $client->request($requestType, $url, $options);
    $body = $response->getBody();

    return $body;
}

The problem resides here, the getBody() method returns a stream, and if I use getBody()->getContents() I get a string, none of which can help me.

Any idea on how can I get the access token so I can finish the authentication process?

1

1 Answers

4
votes

To answer the question itself - you just need to cast $body to string. It should be a json, so you will also need to json_decode it to use it as an object in the code above. So instead of return $body; in your runCurl, you need to do:

return json_decode((string)$body);

I would recommend to use the official client tho. The code in the question has some unrelated issues, which will make it costy to maintain.