Как сохранить access_token в БД, используя логин yii2-dektrium facebook?

я использую yii2-dektrium чтобы позволить пользователям войти в систему со своими учетными записями Facebook.

После входа в систему мне нужно сделать запрос API с моего сервера, чтобы получить данные учетных записей пользователя. Одним из примеров запроса является:

$client = Yii::$app->authClientCollection->getClient('facebook');
$response = $client->createApiRequest()
->setMethod('GET')
->setUrl('v2.12/me/accounts')
->send();

access_token сохраняется в сеансе, поэтому мне нужно сохранить его в базе данных.

Я уже добавил колонку access_token к social_account таблица по умолчанию yii2-dektrium но я не знаю, как получить и сохранить его, и, более того, как применить его к запросам.

Прочитав некоторое время. Я думаю, что способ сохранить это переопределение метода connect в dektrium\user\controllers\SecurityController,

public function connect(ClientInterface $client)
{
/** @var Account $account */
$account = \Yii::createObject(Account::className());
$event   = $this->getAuthEvent($account, $client);
$this->trigger(self::EVENT_BEFORE_CONNECT, $event);
$account->connectWithUser($client);
$this->trigger(self::EVENT_AFTER_CONNECT, $event);
$this->action->successUrl = Url::to(['/user/settings/networks']);
}

А для подачи заявки на запрос переопределить applyAccessTokenToRequest на yii\authclient\clients\Facebook

public function applyAccessTokenToRequest($request, $accessToken)
{
parent::applyAccessTokenToRequest($request, $accessToken);
$data = $request->getData();
if (($machineId = $accessToken->getParam('machine_id')) !== null) {
$data['machine_id'] = $machineId;
}
$data['appsecret_proof'] = hash_hmac('sha256', $accessToken->getToken(), $this->clientSecret);
$request->setData($data);
}

Я не могу сделать это. И я не уверен, что это правильный способ сделать это. Что мне не хватает?

0

Решение

Для сохранения access_token в первый раз вы должны перезаписать connect действие от \dektrium\user\controllers\SecurityController,

class SecurityController extends \dektrium\user\controllers\SecurityController
{
public function connect(ClientInterface $client)
{
// default implementation of connect
$account = \Yii::createObject(Account::className());
$event   = $this->getAuthEvent($account, $client);
$this->trigger(self::EVENT_BEFORE_CONNECT, $event);
$account->connectWithUser($client);
$this->trigger(self::EVENT_AFTER_CONNECT, $event);

// get acess_token from $client
$access_token['tokenParamKey'] = $client->getAccessToken()->tokenParamKey;
$access_token['tokenSecretParamKey'] = $client->getAccessToken()->tokenSecretParamKey;
$access_token['createTimestamp'] = $client->getAccessToken()->createTimestamp;
$access_token['_expireDurationParamKey'] = $client->getAccessToken()->getExpireDurationParamKey();
$access_token['_params'] = $client->getAccessToken()->getParams();

// save acess_token to social_account table
$model = SocialAccount::find()->where(['provider' => $client->getName()])->andWhere(['user_id' => Yii::$app->user->id])->one();
$model->access_token = \yii\helpers\Json::encode($access_token);
$model->save(false);

$this->action->successUrl = Url::to(['/user/settings/networks']);
}
}

Чтобы получить access_token сохранить в базе данных для дальнейших запросов API создать класс, который расширяет yii\authclient\SessionStateStorage и перезаписать get метод.

namespace app\models\authclient;

class DbStateStorage extends SessionStateStorage
{
public function get($key)
{
// $key is a complex string that ends with 'token' if the value to get is the actual access_token
$part = explode('_', $key);
if (count($part) == 3 && $part[2] == 'token') {
$account = SocialAccount::find()
->where(['provider' => $part[1]])
->andWhere(['user_id' => Yii::$app->user->id])
->one();
if ($account != null) {
$access_token = json_decode($account->access_token);
$token = new \yii\authclient\OAuthToken();
$token->createTimestamp = $access_token->createTimestamp;
$token->tokenParamKey = $access_token->tokenParamKey;
$token->tokenSecretParamKey = $access_token->tokenSecretParamKey;
$token->setParams((array)$access_token->_params);
$token->setExpireDurationParamKey($access_token->_expireDurationParamKey);
return $token;
}
}
if ($this->session !== null) {
return $this->session->get($key);
}
return null;
}
}

Наконец установить DbStateStorage на ваш authclient

class Facebook extends \dektrium\user\clients\Facebook
{
public function __construct()
{
$this->setStateStorage('app\models\authclient\DbStateStorage');
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]