Плагин Yii2 и OAuth2 Filsh / yii2-oauth2-server: не авторизован при отправке данных POST


РЕДАКТИРОВАТЬ: РЕШЕНО

Видимо этот плагин, возникли некоторые проблемы отсутствует заголовки запроса. Решение было добавление

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

В файле .htaccess сделать переменную Authorizaion доступной, так как в этом отчете о проблемах говорится:

https://github.com/yiisoft/yii2/issues/6631

В настоящее время я работаю с Yii2 и использую этот плагин OAuth2 (Filsh / yii2-oauth2-server) для входа и работы с токенами из мобильного приложения HTML5.

Я все настроил, и он извлекает токен, но когда я пытаюсь отправить токен через POST, он выдает ошибку.

Я начинаю звонить send() чтобы получить токен.

function send(){
var url = "http://www.server.org/app/api/oauth2/rest/token";
var data = {
'grant_type':'password',
'username':'user',
'password':'pass',
'client_id':'clientid',
'client_secret':'clientsecret',
};

$.ajax({
type: "POST",
url: url,
data: data,
success:function(data){
console.log(data);
token = data.access_token;
},
})
};

Затем, когда я выполняю этот вызов createuser(),

function createuser(){
var url = "http://www.server.org/app/api/v1/users/create";
var data = {
'callback':'asdf',
'username': 'user',
'password':'pass',
'first_name':'name',
'last_name':'lastname'
};

$.ajax({
type: "POST",
url: url,
data: data,
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
},
success:function(r){
console.log(r);
},
});
}

Возвращается

Несанкционированный: вы запрашиваете с недействительными учетными данными

Когда я переключаюсь на GET, он работает нормально.

Это мой контроллер, я уже использую:

[‘class’ => HttpBearerAuth :: className ()],
[‘class’ => QueryParamAuth :: className (), ‘tokenParam’ => ‘accessToken’],

Как метод аутентификации.

<?php

namespace app\api\modules\v1\controllers;

use Yii;
use app\models\OauthUsers;
use yii\rest\ActiveController;
use yii\web\Response;
use yii\helpers\ArrayHelper;

use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
use filsh\yii2\oauth2server\filters\ErrorToExceptionFilter;
use filsh\yii2\oauth2server\filters\auth\CompositeAuth;

class UsersController extends \yii\web\Controller
{
public function behaviors()
{
return ArrayHelper::merge(parent::behaviors(), [
'authenticator' => [
'class' => CompositeAuth::className(),
'authMethods' => [
['class' => HttpBearerAuth::className()],
['class' => QueryParamAuth::className(), 'tokenParam' => 'accessToken'],
]
],
'exceptionFilter' => [
'class' => ErrorToExceptionFilter::className()
],
'class' => \yii\filters\ContentNegotiator::className(),

]);
}

/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionCreate()
{
$model = new OauthUsers;

try {
if ($model->load($_POST) && $model->save()) {
return $this->redirect(Url::previous());
} elseif (!\Yii::$app->request->isPost) {
$model->load($_GET);
}
} catch (\Exception $e) {
$msg = (isset($e->errorInfo[2]))?$e->errorInfo[2]:$e->getMessage();
$model->addError('_exception', $msg);
}
return "true";
}

}

Это мой объект конфигурации

'oauth2' => [
'class' => 'filsh\yii2\oauth2server\Module',
'tokenParamName' => 'accessToken',
'tokenAccessLifetime' => 3600 * 24,
'storageMap' => [
'user_credentials' => 'app\models\OauthUsers',
],
'grantTypes' => [
'user_credentials' => [
'class' => 'OAuth2\GrantType\UserCredentials',
],
'refresh_token' => [
'class' => 'OAuth2\GrantType\RefreshToken',
'always_issue_new_refresh_token' => true
]
]
]

Это класс OauthUsers

<?php

namespace app\models;

use Yii;
use \app\models\base\OauthUsers as BaseOauthUsers;

/**
* This is the model class for table "oauth_users".
*/
class OauthUsers extends BaseOauthUsers
implements \yii\web\IdentityInterface,\OAuth2\Storage\UserCredentialsInterface

{
/**
* @inheritdoc
*/
public static function findIdentity($id) {
$dbUser = OauthUsers::find()
->where([
"id" => $id
])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}

/**
* @inheritdoc
*/
public static function findIdentityByAccessToken($token, $userType = null) {

$at = OauthAccessTokens::find()
->where(["access_token" => $token])
->one();

$dbUser = OauthUsers::find()
->where(["id" => $at->user_id])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}

/**
* Implemented for Oauth2 Interface
*/
public function checkUserCredentials($username, $password)
{
$user = static::findByUsername($username);
if (empty($user)) {
return false;
}
return $user->validatePassword($password);
}

/**
* Implemented for Oauth2 Interface
*/
public function getUserDetails($username)
{
$user = static::findByUsername($username);
return ['user_id' => $user->getId()];
}

/**
* Finds user by username
*
* @param  string      $username
* @return static|null
*/
public static function findByUsername($username) {
$dbUser = OauthUsers::find()
->where([
"username" => $username
])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}

/**
* @inheritdoc
*/
public function getId()
{
return $this->id;
}

/**
* @inheritdoc
*/
public function getAuthKey()
{
return $this->authKey;
}

/**
* @inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}

/**
* Validates password
*
* @param  string  $password password to validate
* @return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}

Я изменился createuser тоже, но все еще получаю 401. Я не уверен, что он проходит через findIdentityByAccessToken (access_token находится в другой таблице, чем пользователи oauth, поэтому я сначала запрашиваю его).

Какие-нибудь мысли?

3

Решение

Я не знаю, какой плагин вы используете, но я знаю, что вы можете использовать Yii2 HttpBearerAuth фильтр при реализации OAuth 2.0 что означает использование HTTP-токен на предъявителя. И этот токен обычно передается с заголовком Authorization HTTP-запроса, а не с запросом body, и обычно выглядит так:

Authorization: Bearer y-9hFW-NhrI1PK7VAXYdYukwWVrNTkQ1

Идея заключается в сохранении token вы получили от сервера где-то (должно быть безопасное место) и включили его в заголовки запросов, требующих авторизации на сервере (может быть, лучше объяснить Вот, Вот или же Вот) Поэтому код JS, который вы используете для отправки запроса POST, должен выглядеть примерно так:

function createuser(){
var url = "http://www.server.org/app/api/v1/users/create";
var data = {
'callback':'cb',
'username': 'user',
'password':'pass',
'first_name':'name',
'last_name':'lastname'
};

$.ajax({
type: "POST",
url: url,
data: data,
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
},
success:function(r){
console.log(r);
},
});
}

Также проверьте в классе User (тот, который определен в ваших конфигурационных файлах и отвечает за аутентификацию пользователя), проверьте реализацию findIdentityByAccessToken () метод. это обычно должно выглядеть так (увидеть Yii документы Больше подробностей):

public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['auth_key' => $token]);
}

Это функция, которая получит token и он должен вернуться null когда аутентификация не удалась (по умолчанию findOne () возвращает ноль, если запись не найдена) или возвращает экземпляр пользователя, чтобы зарегистрировать его и сделать его доступным в Yii::$app->user->identity или же Yii::$app->user->id в любом месте вашего приложения, чтобы вы могли реализовать в нем любую логику, например, проверку правильности маркера доступа или его существования в другой таблице.

1

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

По-видимому, у этого плагина (Filsh / yii2-oauth2-server) возникли некоторые проблемы с пропуском заголовков запросов. Решение было добавление

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

В файл .htaccess, чтобы сделать переменную Authorizaion доступной, как это говорит:

https://github.com/yiisoft/yii2/issues/6631
0

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