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://github.com/namelivia/fitbit-http-php

您可以使用 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