web-dev-qa-db-fra.com

400 mauvaise requête lors du POST sur la page de rasoir

Ma page a ...

@page "{candidateId:int}"

... et

@Html.AntiForgeryToken()

Le modèle a ...

public void OnGet(int candidateId)
{

}

public void OnPost(int candidateId)
{

}

GET fonctionne bien. Voici ma AJAX ..

$.ajax({
    type: "POST",
    url: "/Skills/" + candidateId,
    beforeSend: function (xhr) {

        xhr.setRequestHeader("XSRF-TOKEN",
            $('input:hidden[name="__RequestVerificationToken"]').val());
    },
    data: {

        name: 'hi mum'
    },

    success: function (response) {
    },
    failure: function (response) {

        alert(response);
    }
});

Le navigateur reçoit un message d'erreur inutile ... 400 Bad Request.

Qu'est-ce que je rate?

11
Ian Warburton

Vous obtenez une réponse 400 (Bad Request) car le framework attend le RequestVerificationToken dans le cadre de la requête publiée. Le framework l'utilise pour empêcher d'éventuelles attaques CSRF. Si votre demande ne contient pas ces informations, le framework retournera la 400 mauvaise requête. Votre code actuel ne l'envoie pas.

Changez le code en ceci

headers:
{
    "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},

Cela ajoutera un nouvel élément avec la clé RequestVerificationToken à l'en-tête de la demande et le framework ne devrait pas envoyer de réponse 400 lorsque l'appel est effectué. (en supposant que votre code d'affichage a généré l'entrée masquée pour l'entrée masquée __RequestVerificationToken)

Vous pouvez rendre le code plus robuste en injectant l'implémentation IAntiforgery dans la vue/page et en utilisant la méthode GetAndStoreTokens.

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
    return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}

et appelez cette fonction GetAntiXsrfRequestToken pour obtenir la valeur dans votre javascript

headers:
{
    "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},

Vous voudrez probablement aussi utiliser la propriété CandidateId du PageModel pour créer l'url. Quelque chose comme ça

url: "/Skills/@Model.CandidateId",

De plus, vous devez appeler explicitement la méthode @Html.AntiForgeryToken() pour générer l'entrée de jeton. Le fait d'avoir un formulaire avec la méthode post sans valeur d'attribut d'action générera l'entrée cachée pour vous.

<form method="post">
   <!-- your inputs-->
</form>
18
Shyju