Currently, I am working/integrating Fitbit API on my Yii2 framework.
Code sample like this:
if($_SERVER['HTTP_HOST'] == 'localhost'){ define('REDIRECT_URI', 'https://localhost/yii/contest/FitbitDeviceChange'); }else{ define('REDIRECT_URI', "https://".$_SERVER['HTTP_HOST']."/site/SocialSiteFitfit"); } define('HOST', 'https://api.fitbit.com/'); define('ACCESS_TOKEN_URL', 'https://api.fitbit.com/oauth2/token'); define('AUTHENTICATE_URL', 'https://www.fitbit.com/oauth2/authorize'); class FitbitApiController extends FrontController { private $accessToken = null; private $refreshToken = null; private $expires = 31536000; public $CLIENT_ID = ''; public $CLIENT_SECRET = ''; public $REDIRECT_URI = REDIRECT_URI; /** * fn getAuthorizationCode() launch the authorization page * */ public static function getAuthorizationCode($CLIENT_ID) { $url = AUTHENTICATE_URL.'?response_type=code&prompt=login consent&client_id='.$CLIENT_ID. '&redirect_uri='.urlencode(REDIRECT_URI). '&scope=activity%20profile&expires_in=31536000'; header('Location: '.$url); } }
API Integration is currently done and working fine, but after a certain time token expired, I never want customers again and again to accept a request, I want customers to accept requests once and never expired token and not need to connect again and again.
Any Idea how to prevent token expiration?
My refresh code URL is: https://github.com/namelivia/fitbit-http-php
Advertisement
Answer
You can use URL ‘https://api.fitbit.com/oauth2/revoke’ and your existing access_token for refresh or regenerate.
public function revoke(AccessToken $accessToken) { $options = $this->getOptionProvider() ->getAccessTokenOptions(self::METHOD_POST, []); $uri = $this->appendQuery( 'https://api.fitbit.com/oauth2/revoke/oauth2/revoke', $this->buildQueryString(['token' => $accessToken->getToken()]) ); $request = $this->getRequest(self::METHOD_POST, $uri, $options); return $this->getResponse($request); }
Full Example are:
<?php namespace djchenOAuth2ClientProvider; use LeagueOAuth2ClientProviderAbstractProvider; use LeagueOAuth2ClientProviderExceptionIdentityProviderException; use LeagueOAuth2ClientTokenAccessToken; use LeagueOAuth2ClientToolBearerAuthorizationTrait; use PsrHttpMessageResponseInterface; class Fitbit extends AbstractProvider { use BearerAuthorizationTrait; /** * Fitbit URL. * * @const string */ const BASE_FITBIT_URL = 'https://www.fitbit.com'; /** * Fitbit API URL. * * @const string */ const BASE_FITBIT_API_URL = 'https://api.fitbit.com'; /** * HTTP header Accept-Language. * * @const string */ const HEADER_ACCEPT_LANG = 'Accept-Language'; /** * HTTP header Accept-Locale. * * @const string */ const HEADER_ACCEPT_LOCALE = 'Accept-Locale'; /** * Overridden to inject our options provider * @param array $options * @param array $collaborators */ public function __construct(array $options = [], array $collaborators = []) { $collaborators['optionProvider'] = new FitbitOptionsProvider( $options['clientId'], $options['clientSecret'] ); parent::__construct($options, $collaborators); } /** * Get authorization url to begin OAuth flow. * * @return string */ public function getBaseAuthorizationUrl() { return static::BASE_FITBIT_URL.'/oauth2/authorize'; } /** * Get access token url to retrieve token. * * @param array $params * * @return string */ public function getBaseAccessTokenUrl(array $params) { return static::BASE_FITBIT_API_URL.'/oauth2/token'; } /** * Returns the url to retrieve the resource owners's profile/details. * * @param AccessToken $token * * @return string */ public function getResourceOwnerDetailsUrl(AccessToken $token) { return static::BASE_FITBIT_API_URL.'/1/user/-/profile.json'; } /** * Returns all scopes available from Fitbit. * It is recommended you only request the scopes you need! * * @return array */ protected function getDefaultScopes() { return ['activity', 'heartrate', 'location', 'profile', 'settings', 'sleep', 'social', 'weight', 'nutrition']; } /** * Checks Fitbit API response for errors. * * @throws IdentityProviderException * * @param ResponseInterface $response * @param array|string $data Parsed response data */ protected function checkResponse(ResponseInterface $response, $data) { if ($response->getStatusCode() >= 400) { $errorMessage = ''; if (!empty($data['errors'])) { foreach ($data['errors'] as $error) { if (!empty($errorMessage)) { $errorMessage .= ' , '; } $errorMessage .= implode(' - ', $error); } } else { $errorMessage = $response->getReasonPhrase(); } throw new IdentityProviderException( $errorMessage, $response->getStatusCode(), $response ); } } /** * Returns the string used to separate scopes. * * @return string */ protected function getScopeSeparator() { return ' '; } /** * Returns authorization parameters based on provided options. * Fitbit does not use the 'approval_prompt' param and here we remove it. * * @param array $options * * @return array Authorization parameters */ protected function getAuthorizationParameters(array $options) { $params = parent::getAuthorizationParameters($options); unset($params['approval_prompt']); if (!empty($options['prompt'])) { $params['prompt'] = $options['prompt']; } return $params; } /** * Generates a resource owner object from a successful resource owner * details request. * * @param array $response * @param AccessToken $token * * @return FitbitUser */ public function createResourceOwner(array $response, AccessToken $token) { return new FitbitUser($response); } /** * Returns the key used in the access token response to identify the resource owner. * * @return string|null Resource owner identifier key */ protected function getAccessTokenResourceOwnerId() { return 'user_id'; } /** * Revoke access for the given token. * * @param AccessToken $accessToken * * @return mixed */ public function revoke(AccessToken $accessToken) { $options = $this->getOptionProvider() ->getAccessTokenOptions(self::METHOD_POST, []); $uri = $this->appendQuery( self::BASE_FITBIT_API_URL.'/oauth2/revoke', $this->buildQueryString(['token' => $accessToken->getToken()]) ); $request = $this->getRequest(self::METHOD_POST, $uri, $options); return $this->getResponse($request); } public function parseResponse(ResponseInterface $response) { return parent::parseResponse($response); } /** * Parse Fitbit API Rate Limit headers and return a FitbitRateLimit object. * * @param ResponseInterface $response * * @return FitbitRateLimit Fitbit API Rate Limit information */ public function getFitbitRateLimit(ResponseInterface $response) { return new FitbitRateLimit($response); } }
You should read fitbit auth2 document also for more details about parameters: https://dev.fitbit.com/build/reference/web-api/oauth2/
and check full code : https://github.com/djchen/oauth2-fitbit/tree/master/src/Provider