enableDebug(); $auth_failure = false; // Try to make request using stored token try { $o->setToken( $access_token, $access_secret ); if( $o->fetch( $url ) ) { print "Got data from API:\n\n"; print $o->getLastResponse() . "\n\n"; print "Successful!\n"; exit; } else { print "Couldn'\t fetch\n"; } } catch( OAuthException $e ) { print 'Error: ' . $e->getMessage() . "\n"; print 'Error Code: ' . $e->getCode() . "\n"; print 'Response: ' . $e->lastResponse . "\n"; if( $e->getCode() == 401 ) { $auth_failure = true; } } // 2. If we get an auth error, try to refresh the token using the session. if( $auth_failure ) { try { $response = $o->getAccessToken( 'https://api.login.yahoo.com/oauth/v2/get_token', $access_session, $access_verifier ); } catch( OAuthException $e ) { print 'Error: ' . $e->getMessage() . "\n"; print 'Response: ' . $e->lastResponse . "\n"; $response = NULL; } print_r( $response ); if( $response ) { $access_token = $response['oauth_token']; $access_secret = $response['oauth_token_secret']; $access_session = $response['oauth_session_handle']; $store_access_token_data = true; print "Was able to refresh access token:\n"; print " Token: ${access_token}\n"; print " Secret: ${access_secret}\n"; print " Session Handle: ${access_session}\n\n"; } else { $access_token = NULL; $access_secret = NULL; $access_session = NULL; print "Unable to refresh access token, will need to request a new one.\n"; } } } // 3. If none of that worked, send the user to get a new token if( ! $access_token ) { print "Better try to get a new access token.\n"; $o = new OAuth( $consumer_key, $consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI ); $o->enableDebug(); $request_token = NULL; try { $response = $o->getRequestToken( "https://api.login.yahoo.com/oauth/v2/get_request_token", 'oob' ); $request_token = $response['oauth_token']; $request_secret = $response['oauth_token_secret']; print "Hey! Go to this URL and tell us the verifier you get at the end.\n"; print ' ' . $response['xoauth_request_auth_url'] . "\n"; } catch( OAuthException $e ) { print $e->getMessage() . "\n"; } // Wait for input, then try to use it to get a new access token. if( $request_token && $request_secret ) { print "Type the verifier and hit enter...\n"; $verifier = fgets( STDIN ); $verifier = rtrim( $verifier ); print "Here's the verifier you gave us: ${verifier}\n"; try { $o->setToken( $request_token, $request_secret ); $response = $o->getAccessToken( 'https://api.login.yahoo.com/oauth/v2/get_token', NULL, $verifier ); print "Got it!\n"; $access_token = $response['oauth_token']; $access_secret = $response['oauth_token_secret']; $access_session = $response['oauth_session_handle']; $store_access_token_data = true; print " Token: ${access_token}\n"; print " Secret: ${access_secret}\n"; print " Session Handle: ${access_session}\n\n"; } catch( OAuthException $e ) { print 'Error: ' . $e->getMessage() . "\n"; print 'Response: ' . $e->lastResponse . "\n"; print "Shoot, couldn't get the access token. :(\n"; } } } if( $access_token ) { // Try to make request using stored token try { $o->setToken( $access_token, $access_secret ); if( $o->fetch( $url ) ) { print "Got data from API:\n\n"; print $o->getLastResponse() . "\n\n"; print "Successful!\n"; } else { print "Couldn'\t fetch\n"; } } catch( OAuthException $e ) { print 'Error: ' . $e->getMessage() . "\n"; print 'Error Code: ' . $e->getCode() . "\n"; print 'Response: ' . $e->lastResponse . "\n"; } } // 4. Rewrite token information if necessary if( $store_access_token_data ) { print "Looks like we need to store access token data! Doing that now.\n"; $tok_fh = fopen( $token_file_name, 'w' ); if( $tok_fh ) { fwrite( $tok_fh, "${access_token}\n" ); fwrite( $tok_fh, "${access_secret}\n" ); fwrite( $tok_fh, "${access_session}\n" ); fclose( $tok_fh ); } else { print "Hm, couldn't open file to write back access token information.\n"; } } ?> Full OAuth Flow without Libraries¶ If the PHP library described above doesn’t fit your needs, you may feel like implementing the flow yourself. It’s mildly tricky and you may run into common issues like not sorting the parameters correctly, or not encoding the various parts of the URL at the right time. The following script is an example of doing absolutely everything from scratch, and may be a useful guide for you. '; $consumer_data['test']['secret'] = ''; // **** HELPER FUNCTIONS START HERE **** /////////////////////////////////////////////////////////////////////////////// // FUNCTION _make_signed_request /// @brief Helper function to make a signed OAuth request. Only allows GET /// requests at the moment. Will add on standard OAuth params, but /// you may need to fill in non-generic ones ahead of time. /// /// @param[in] $consumer_key Application consumer key /// @param[in] $consumer_secret Application consumer secret /// @param[in] $token Token (request or access token) /// @param[in] $token_secret Token secret /// @param[in] $signature_method 'PLAINTEXT' or 'HMAC-SHA1' /// @param[in] $url URL to make request to /// @param[in] $params Array of key=>val for params. Don't /// urlencode ahead of time, we'll do that here. /////////////////////////////////////////////////////////////////////////////// function _make_signed_request( $consumer_key, $consumer_secret, $token, $token_secret, $signature_method, $url, $params = array() ) { // Only support GET in this function $method = 'GET'; $signature_method = strtoupper( $signature_method ); if( $signature_method != 'PLAINTEXT' && $signature_method != 'HMAC-SHA1' ) { print "Invalid signature method: ${signature_method}\n"; return false; } $oauth_nonce = rand( 0, 999999 ); $oauth_timestamp = time(); $oauth_version = '1.0'; $params['oauth_consumer_key'] = $consumer_key; $params['oauth_nonce'] = $oauth_nonce; $params['oauth_signature_method'] = $signature_method; $params['oauth_timestamp'] = $oauth_timestamp; $params['oauth_version'] = $oauth_version; if( $token ) { $params['oauth_token'] = $token; } if( ! $token_secret ) { $token_secret = ''; } // Params need to be sorted by key ksort( $params, SORT_STRING ); // Urlencode params and generate param string $param_list = array(); foreach( $params as $key => $value ) { $param_list[] = urlencode( $key ) . '=' . urlencode( $value ); } $param_string = join( '&', $param_list ); // Generate base string (needed for SHA1) $base_string = urlencode( $method ) . '&' . urlencode( $url ) . '&' . urlencode( $param_string ); // Generate secret $secret = urlencode( $consumer_secret ) . '&' . urlencode( $token_secret ); if( $signature_method == 'PLAINTEXT' ) { $signature = $secret; } else if( $signature_method == 'HMAC-SHA1' ) { $signature = base64_encode( hash_hmac( 'sha1', $base_string, $secret, true ) ); } // Append signature $param_string .= '&oauth_signature=' . urlencode( $signature ); $final_url = $url . '?' . $param_string; // Make curl call $ch = curl_init(); curl_setopt( $ch, CURLOPT_URL, $final_url ); curl_setopt( $ch, CURLOPT_AUTOREFERER, 1 ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 0 ); curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 ); $timeout = 2; // seconds curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout ); curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout ); $contents = curl_exec($ch); $ret_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); $errno = curl_errno($ch); $error_str = curl_error($ch); if( $errno || $error_str ) { //print "Error: ${error_str} (${errno})\n"; } //print "Response code: ${ret_code}\n"; //print "Contents:\n${contents}\n\n"; curl_close($ch); $data = array( 'return_code' => $ret_code, 'contents' => $contents, 'error_str' => $error_str, 'errno' => $errno ); return $data; } /////////////////////////////////////////////////////////////////////////////// // FUNCTION oauth_response_to_array /// @brief Break up the oauth response data into an associate array /////////////////////////////////////////////////////////////////////////////// function oauth_response_to_array( $response ) { $data = array(); foreach( explode( '&', $response ) as $param ) { $parts = explode( '=', $param ); if( count( $parts ) == 2 ) { $data[urldecode($parts[0])] = urldecode($parts[1]); } } return $data; } /////////////////////////////////////////////////////////////////////////////// // FUNCTION get_request_token /// @brief Get a request token for a given application. /////////////////////////////////////////////////////////////////////////////// function get_request_token( $consumer_key, $consumer_secret ) { $url = 'https://api.login.yahoo.com/oauth/v2/get_request_token'; $signature_method = 'plaintext'; $token = NULL; $token_secret = NULL; // Add in the lang pref and callback $xoauth_lang_pref = 'en-us'; $oauth_callback = 'oob'; // Set OOB for ease of use -- could be a URL $params = array( 'xoauth_lang_pref' => $xoauth_lang_pref, 'oauth_callback' => $oauth_callback ); // Make the signed request without any token $response_data = _make_signed_request( $consumer_key, $consumer_secret, $token, $token_secret, $signature_method, $url, $params ); if( $response_data && $response_data['return_code'] == 200 ) { $contents = $response_data['contents']; $data = oauth_response_to_array( $contents ); //print_r( $data ); return $data; } return false; } /////////////////////////////////////////////////////////////////////////////// // FUNCTION get_access_token /// @brief Get an access token for a certain user and a certain application, /// based on the request token and verifier /////////////////////////////////////////////////////////////////////////////// function get_access_token( $consumer_key, $consumer_secret, $request_token, $request_token_secret, $verifier ) { $url = 'https://api.login.yahoo.com/oauth/v2/get_token'; $signature_method = 'plaintext'; // Add in the oauth verifier $params = array( 'oauth_verifier' => $verifier ); // Make the signed request using the request_token data $response_data = _make_signed_request( $consumer_key, $consumer_secret, $request_token, $request_token_secret, $signature_method, $url, $params ); if( $response_data && $response_data['return_code'] == 200 ) { $contents = $response_data['contents']; $data = oauth_response_to_array( $contents ); //print_r( $data ); return $data; } return false; } /////////////////////////////////////////////////////////////////////////////// // FUNCTION make_request /// @brief Make an actual request to the fantasy API. /////////////////////////////////////////////////////////////////////////////// function make_request( $consumer_key, $consumer_secret, $access_token, $access_token_secret, $url ) { $signature_method = 'hmac-sha1'; // Make the signed request to fantasy API $response_data = _make_signed_request( $consumer_key, $consumer_secret, $access_token, $access_token_secret, $signature_method, $url ); return $response_data; } // **** MAIN PROGRAM STARTS HERE **** $consumer_key = $consumer_data['test']['key']; $consumer_secret = $consumer_data['test']['secret']; // 1. Get Request Token $request_token_data = get_request_token( $consumer_key, $consumer_secret ); if( ! $request_token_data ) { print "Could not retrieve request token data\n"; exit; } $request_token = $request_token_data['oauth_token']; $request_token_secret = $request_token_data['oauth_token_secret']; $auth_url = $request_token_data['xoauth_request_auth_url']; // 2. Direct user to Yahoo! for authorization (retrieve verifier) print "Hey! Go to this URL and tell us the verifier you get at the end.\n"; print ' ' . $auth_url . "\n\n"; print "Type the verifier and hit enter...\n"; $verifier = fgets( STDIN ); print "Here's the verifier you gave us: ${verifier}\n"; // 3. Get Access Token $access_token_data = get_access_token( $consumer_key, $consumer_secret, $request_token, $request_token_secret, $verifier ); if( ! $access_token_data ) { print "Could not get access token\n"; exit; } $access_token = $access_token_data['oauth_token']; $access_token_secret = $access_token_data['oauth_token_secret']; // 4. Make request using Access Token $base_url = 'https://fantasysports.yahooapis.com/'; if( isset( $argv[1] ) ) { $request_uri = $argv[1]; } else { $request_uri = 'fantasy/v2/game/nfl'; } $request_url = $base_url . $request_uri; print "Making request for ${request_url}...\n"; $request_data = make_request( $consumer_key, $consumer_secret, $access_token, $access_token_secret, $request_url ); if( ! $request_data ) { print "Request failed\n"; } $return_code = $request_data['return_code']; $contents = $request_data['contents']; print "Return code: ${return_code}\n"; print "Contents:\n${contents}\n\n"; print "Successful\n"; ?> PUTs and POSTs¶ The default PHP OAuth extension does not support any methods aside from GET (as far as I can tell), but we do have write operations as part of the Fantasy API that you might want to make use of. The easiest solution would be to find a library that does support PUTs and POSTs (and DELETEs), but failing that, you can check out this quick sample code that will execute a PUT or POST given an access token (see earlier scripts for how to retrieve an access token). $oauth_consumer_key, 'oauth_nonce' => $oauth_nonce, 'oauth_signature_method' => $oauth_signature_method, 'oauth_timestamp' => $oauth_timestamp, 'oauth_token' => $oauth_token, 'oauth_version' => $oauth_version, ); // Params need to be sorted by key ksort( $params, SORT_STRING ); // Urlencode params and generate param string $param_list = array(); foreach( $params as $key => $value ) { $param_list[] = urlencode( $key ) . '=' . urlencode( $value ); } $param_string = join( '&', $param_list ); // Generate base string (needed for SHA1) $base_string = urlencode( $method ) . '&' . urlencode( $url ) . '&' . urlencode( $param_string ); // Generate secret and signature $secret = urlencode( $consumer_secret ) . '&' . urlencode( $oauth_token_secret ); $signature = base64_encode( hash_hmac( 'sha1', $base_string, $secret, true ) ); // Append signature $final_url = $url . '?' . $param_string . '&oauth_signature=' . urlencode( $signature ); // Make the curl call $ch = curl_init(); curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Content-type: application/xml' ) ); if( $method == 'POST' ) { curl_setopt( $ch, CURLOPT_POST, 1 ); curl_setopt( $ch, CURLOPT_POSTFIELDS, $input_data ); } else if( $method == 'PUT' ) { fseek( $in_fh, 0 ); curl_setopt( $ch, CURLOPT_PUT, 1 ); curl_setopt( $ch, CURLOPT_INFILE, $in_fh ); curl_setopt( $ch, CURLOPT_INFILESIZE, strlen( $input_data ) ); } curl_setopt( $ch, CURLOPT_URL, $final_url ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); $ycw_result = curl_exec( $ch ); $ret_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); fclose( $in_fh ); curl_close( $ch ); if( $ret_code == 401 ) { $auth_failure = true; } else { $response_success = true; } print "Return code: ${ret_code}\n"; print "Response from API:\n"; print_r( $ycw_result ); return $response_success; } ?>