Вот у меня пользователи могут подписываться на пост определенный и для этого есть кнопка "подписаться".
Код во вьюхе такой:
<div id="subscribe" class="btn_subscribe" data-user-id="<?= $user->id ?>"
data-post-id="<?= $modelPost->id ?>"
data-user-subscribe="0">
</div>
Соответственно скрипт отправляет id пользователя и id поста, на который он хочет подписаться.
Код запроса:
$('#subscribe').on('click', function (e) {
var el = document.querySelector('#subscribe');
var dataToServer = '';
dataToServer += 'userID=';
dataToServer += el.dataset.userId;
dataToServer += '&postID=';
dataToServer += el.dataset.postId;
$.ajax({
async: true,
cache: false,
type: "POST",
url: url,
data: dataToServer,
dataType: "html",
ifModified: true,
timeout: 10000,
dataFilter: function (data, type) {
var answer = JSON.parse(data);
console.log(answer);
}
});
});
Код экшена упрощенный такой:
public function actionChangeEvent()
{
if (Yii::$app->request->isAjax && isset($_POST['userID']) && isset($_POST['postID'])) {
if ($_POST['userID'] == 0) {
return json_encode(['no user', 0]);
}
$user = User::findOne($_POST['userID']);
$post = Post::findOne($_POST['postID']);
if (isset($user) && isset($post)) {
$alreadySubscribe = Subscribe::find()
->where(['userID' => $user->id])
->andWhere(['postID' => $post->id])
->one();
if (isset($alreadySubscribe)) {
// пользователь хочет отписаться
$alreadySubscribe->delete();
return json_encode(['removed success', Subscribe::find()->where(['postID' => $post->id])->count()]);
} else {
// пользователь хочет подписаться
$subscribe = new Subscribe();
$subscribe->createdAT = date("Y-m-d H:i:s");
$subscribe->userID = $user->id;
$subscribe->postID = $post->id;
$subscribe->save();
return json_encode(['added success', Subscribe::find()->where(['postID' => $post->id])->count()]);
}
}
} else {
echo 'ошибка';
}
}
Так вот, текущая реализация полностью устраивает кроме безопасности - можно легко подменить идшники пользователя или поста и накрутить подписки. Для этого очевидно нужно как-то удостовериться что запрос идет именно от авторизованного пользователя и именно свой айдишник он отправляет в запросе, а не чужой. Идеи есть, но уверен что есть какие-то лучшие практики..
Да, csrf валидация мне по-прежнему не понятно как работает и можно ли ее использовать в данном контексте для решения этой задачи.. Все варианты интересны, заранее благодарен за ответы.