Answer the question
In order to leave comments, you need to log in
What is the best practice to validate a request via ajax?
Here I have users can subscribe to a certain post and for this there is a "subscribe" button.
The code in the view is like this:
<div id="subscribe" class="btn_subscribe" data-user-id="<?= $user->id ?>"
data-post-id="<?= $modelPost->id ?>"
data-user-subscribe="0">
</div>
$('#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 'ошибка';
}
}
Answer the question
In order to leave comments, you need to log in
1) You need to remove sending user id via Ajax. It doesn't matter at all.
2) user id must be taken from the current authorized user (In Yii, something like Yii::$app->user->id )
$_POST['userID']
Not the best idea to get parameters directly from $_POST, there is Yii::$app->request->getBodyParams() for that.
If you have a standard implementation of authorization, then for authorized users in Yii::$app->user->id will be the id of the current user.
Good afternoon.
About accessing the global array directly and getting the user id has already been written more than once.
And checking the csrf token can be done like this:
in the view
$this->registerJs('
$("#subscribe").on("click", function(e){
$.ajax({
method: "POST",
data: {id: $(this).attr("data-post-id"),_csrf: "' . Yii::$app->request->csrfToken . '"},
success: function(data){
console.log(data)
}
})
})
', View::POS_END)
if(Yii::$app->request->isAjax){
if(Yii::$app->request->validateCsrfToken()){
// продолжаем выполнение кода.
}
else{
return 'Error Csrf Token';
}
}
$user = User::findOne($_POST['userID']);
should be replaced with the $user = User::findOne(['id' => Yii::$app->user->identity->id]);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question