Fitbit Auth 2 Api 没有令牌的集成已过期
Fitbit Auth 2 Api integration without Token expired
目前,我在 Yii2 框架上 working/integrating Fitbit API。
代码示例如下:
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 集成目前已经完成并且工作正常,但是在某个时间令牌过期后,我不想让客户一次又一次地接受请求,我想要客户接受请求一次,令牌永不过期,不需要一次又一次地连接。
知道如何防止令牌过期吗?
您可以使用 URL 'https://api.fitbit.com/oauth2/revoke' 和您现有的 access_token 进行刷新或重新生成。
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);
}
完整的例子是:
<?php
namespace djchen\OAuth2\Client\Provider;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
use Psr\Http\Message\ResponseInterface;
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);
}
}
您还应该阅读 fitbit auth2 文档以了解有关参数的更多详细信息:
https://dev.fitbit.com/build/reference/web-api/oauth2/
并查看完整代码:https://github.com/djchen/oauth2-fitbit/tree/master/src/Provider
目前,我在 Yii2 框架上 working/integrating Fitbit API。
代码示例如下:
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 集成目前已经完成并且工作正常,但是在某个时间令牌过期后,我不想让客户一次又一次地接受请求,我想要客户接受请求一次,令牌永不过期,不需要一次又一次地连接。
知道如何防止令牌过期吗?
您可以使用 URL 'https://api.fitbit.com/oauth2/revoke' 和您现有的 access_token 进行刷新或重新生成。
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);
}
完整的例子是:
<?php
namespace djchen\OAuth2\Client\Provider;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
use Psr\Http\Message\ResponseInterface;
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);
}
}
您还应该阅读 fitbit auth2 文档以了解有关参数的更多详细信息: https://dev.fitbit.com/build/reference/web-api/oauth2/
并查看完整代码:https://github.com/djchen/oauth2-fitbit/tree/master/src/Provider