Skip to content

Commit

Permalink
add example script for demonstrating oAuth2 flow; update README + CHA…
Browse files Browse the repository at this point in the history
…NGELOG
  • Loading branch information
mjaschen committed Sep 16, 2019
1 parent d7dcd49 commit 3d03540
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 44 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
All notable changes to `iamstuartwilson/strava` will be documented in this file.
Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.

## [1.4.0] - 2019-09-16

### Added

- Support for Strava's new oAuth2 flow (short-lived access tokens, refresh tokens).
- Example file which demonstrates how the oAuth2 flow works.

### Changed

- Unified Markdown style in README.

## [1.3.0] - 2017-03-02

### Added

- Possibility to use absolute URL for an endpoint to work with new [webhook functionality](https://developers.strava.com/docs/webhooks/).

## [1.2.2] - 2016-10-26

### Added
Expand Down
91 changes: 47 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,26 @@
![Packagist](https://img.shields.io/packagist/v/iamstuartwilson/strava.svg)
![Packagist Downloads](https://img.shields.io/packagist/dt/iamstuartwilson/strava.svg)

StravaApi
=============
# StravaApi

The class simply houses methods to help send data to and recieve data from the API. Please read the [API documentation](https://developers.strava.com/docs/reference/) to see what endpoints are available.
The class simply houses methods to help send data to and receive data from the API. Please read the [API documentation](https://developers.strava.com/docs/reference/) to see what endpoints are available.

*There is currently no file upload support at this time*
*There is no file upload support at this time.*

Installation
------------
## Installation

### With Composer

``` shell
composer require iamstuartwilson/strava
```
$ composer require iamstuartwilson/strava
```

**Or**

Add `iamstuartwilson/strava` to your `composer.json`:
Or add it manually to your `composer.json`:

``` json
{
"require" : {
"iamstuartwilson/strava" : "~1.3"
"iamstuartwilson/strava" : "^1.4"
}
}
```
Expand All @@ -35,10 +31,9 @@ Add `iamstuartwilson/strava` to your `composer.json`:

Copy `StravaApi.php` to your project and *require* it in your application as described in the next section.

Getting Started
------------
## Getting Started

Include the class and instantiate with your **client_id** and **client_secret** from your [registered app](https://www.strava.com/settings/api):
Instantiate the class with your **client_id** and **client_secret** from your [registered app](https://www.strava.com/settings/api):

``` php
require_once 'StravaApi.php';
Expand All @@ -49,34 +44,58 @@ $api = new Iamstuartwilson\StravaApi(
);
```

You will then need to [authenticate](http://strava.github.io/api/v3/oauth/) your strava account by requesting an access code<sup>1</sup>. You can generate a URL for authentication using the following method:
If you're just testing endpoints/methods you can skip the authentication flow and just use the access token from your [settings page](https://www.strava.com/settings/api).

You will then need to [authenticate](https://developers.strava.com/docs/authentication/) your strava account by requesting an access code. You can generate a URL for authentication using the following method:

``` php
$api->authenticationUrl($redirect, $approvalPrompt = 'auto', $scope = null, $state = null);
```

When a code is returned you must then exchange it for an [access token](http://strava.github.io/api/v3/oauth/#post-token) for the authenticated user:
When a code is returned you must then exchange it for an [access token and a refresh token](http://developers.strava.com/docs/authentication/#token-exchange) for the authenticated user:

``` php
$api->tokenExchange($code);
$result = $api->tokenExchange($code);
```

Before making any requests you must set the access token as returned from your token exchange or via your own private token from Strava:
The token exchange result contains among other data the tokens. You can access them as attributes of the result object:

```php
$accessToken = $result->access_token;
$refreshToken = $result->refresh_token;
$expiresAt = $result->expires_at;
```

Before making any requests you must set the access and refresh tokens as returned from your token exchange result or via your own private token from Strava:

``` php
$api->setAccessToken($accessToken);
$api->setAccessToken($accessToken, $refreshToken, $expiresAt);
```

Example Requests
------------
## Example oAuth2 Authentication Flow

`examples/oauth-flow.php` demonstrates how the oAuth2 authentication flow works.

1. Choose how to load the `StravaApi.php` – either via Composer autoloader or by manually *requiring* it.
2. Replace the three config values `CALLBACK_URL`, `STRAVA_API_ID`, and `STRAVA_API_SECRET` at the top of the file
3. Place the file on your server so that it's accessible at `CALLBACK_URL`
4. Point your browser to `CALLBACK_URL` and start the authentication flow.

The scripts prints a lot of verbose information so you get an idea on how the Strava oAuth flow works.

Get the most recent 100 KOMs from any athlete
## Example Requests

Once successfully authenticated you're able to communicate with Strava's API.

All actions that change Strava contents (`post`, `put`, `delete`) will need the **scope** set to *write* in the authentication flow.

### Get the most recent 100 KOMs from any athlete

``` php
$api->get('athletes/:id/koms', ['per_page' => 100]);
```

Post a new activity<sup>2</sup>
### Post a new activity

``` php
$api->post('activities', [
Expand All @@ -87,34 +106,18 @@ $api->post('activities', [
]);
```

Update a athlete's weight<sup>2</sup>
### Update a athlete's weight

``` php
$api->put('athlete', ['weight' => 70]);
```

Delete an activity<sup>2</sup>
### Delete an activity

``` php
$api->delete('activities/:id');
```

### Notes

**1**. The account you register your app will give you an access token, so you can skip this step if you're just testing endpoints/methods.

**2**. These actions will need the **scope** set to *write* when authenticating a user

---

Releases
---
Latest version **1.3.0**

- Adds possibility to use absolute URL for an endpoint to work with new [webhook functionality](https://developers.strava.com/docs/webhooks/).

Previous version **1.2.2**
## Releases

- Possibility to access the HTTP response headers
- PHP 7 compatibility
- Basic PHPUnit test cases for Auth URL generation
See CHANGELOG.md.
116 changes: 116 additions & 0 deletions examples/oauth-flow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

// Use Composer's autoloader or include the StravaApi class manually:
require_once './vendor/autoload.php';
//require_once 'StravaApi.php';

// Replace with the actual URL of this file:
define('CALLBACK_URL', 'https://example.org/oauth-flow.php?action=callback');
// Insert your Strava App ID + Secret:
define('STRAVA_API_ID', '');
define('STRAVA_API_SECRET', '');

// We save access and refresh tokens as well as the expire timestamp in the session.
// So we've to enable session support:
session_start();

// Instatiate the StravaApi class with API ID and API Secret (replace placeholders!):
$api = new Iamstuartwilson\StravaApi(STRAVA_API_ID, STRAVA_API_SECRET);

// Setup the API instance with authentication tokens, if possible:
if (
!empty($_SESSION['strava_access_token'])
&& !empty($_SESSION['strava_refresh_token'])
&& !empty($_SESSION['strava_access_token_expires_at'])
) {
$api->setAccessToken(
$_SESSION['strava_access_token'],
$_SESSION['strava_refresh_token'],
$_SESSION['strava_access_token_expires_at']
);
}

$action = isset($_GET['action']) ? $_GET['action'] : 'default';

switch ($action) {
case 'auth':
header('Location: ' . $api->authenticationUrl(CALLBACK_URL, 'auto', 'read_all'));

return;

case 'callback':
echo '<h2>Callback Response Data</h2>';
echo '<pre>';
print_r($_GET);
echo '</pre>';
$code = $_GET['code'];
$response = $api->tokenExchange($code);
echo '<h2>Token Exchange Response Data</h2>';
echo '<p>(after swapping the code from callback against tokens)</p>';
echo '<pre>';
print_r($response);
echo '</pre>';

$_SESSION['strava_access_token'] = isset($response->access_token) ? $response->access_token : null;
$_SESSION['strava_refresh_token'] = isset($response->refresh_token) ? $response->refresh_token : null;
$_SESSION['strava_access_token_expires_at'] = isset($response->expires_at) ? $response->expires_at : null;

echo '<h2>Session Contents (after)</h2>';
echo '<pre>';
print_r($_SESSION);
echo '</pre>';

echo '<p><a href="?action=test_request">Send test request</a></p>';
echo '<p><a href="?action=refresh_token">Refresh Access Token</a></p>';

return;

case 'refresh_token':
echo '<h2>Session Contents (before)</h2>';
echo '<pre>';
print_r($_SESSION);
echo '</pre>';

echo '<h2>Refresh Token</h2>';
$response = $api->tokenExchangeRefresh();
echo '<pre>';
print_r($response);
echo '</pre>';

$_SESSION['strava_access_token'] = isset($response->access_token) ? $response->access_token : null;
$_SESSION['strava_refresh_token'] = isset($response->refresh_token) ? $response->refresh_token : null;
$_SESSION['strava_access_token_expires_at'] = isset($response->expires_at) ? $response->expires_at : null;

echo '<h2>Session Contents (after)</h2>';
echo '<pre>';
print_r($_SESSION);
echo '</pre>';

return;

case 'test_request':
echo '<h2>Session Contents</h2>';
echo '<pre>';
print_r($_SESSION);
echo '</pre>';

$response = $api->get('/athlete');
echo '<h2>Test Request (/athlete)</h2>';
echo '<pre>';
print_r($response);
echo '</pre>';

return;

case 'default':
default:
echo '<p>Start authentication flow.</p>';
echo '<p><a href="?action=auth">Start oAuth Authentication Flow</a> (Strava oAuth URL: <code>'
. $api->authenticationUrl(CALLBACK_URL)
. '</code>)</p>';
echo '<h2>Session Contents</h2>';
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
echo '<p><a href="?action=refresh_token">Refresh Access Token</a></p>';
}

0 comments on commit 3d03540

Please sign in to comment.