ASP.Net Core With React Antiforgery token 不起作用

ASP.Net Core With React Antiforgery token not working

提问人:user2038084 提问时间:10/23/2023 更新时间:11/3/2023 访问量:106

问:

我正在尝试使用 ASP.NET Core 7 和 React 开发应用程序,我需要为所有请求实现防伪保护。我已经在网上研究了几天,并尝试了各种解决方案;但是,我仍然不确定如何解决该问题。

以下是我的代码,我可以解决任何其他问题。

程序.CS

builder.Services.AddAntiforgery(
{
        options.Cookie.Name = "X-XSRF-TOKEN";
        options.Header = "X-XSRF-TOKEN";
});

控制器

[Route("/Test2")]
[ValidateAntiForgeryToken]
[HttpPost]
public PostResponse Test2(PostRequest pr)
{
        return RunVehCheck(pr);
}

反应 (.js)

const getCSRFToken = async () => {
        const response = await fetch("https://localhost:7277/Test2", {
            method: "GET"
        });

        const csrfToken = await response.json();
        return csrfToken;
    }

    useEffect(() => {
        getCSRFToken();
    }, []);

    const handleSubmit = async (e) => {
        e.preventDefault()
        fetch("https://localhost:7277/Test2", {
            method: "POST",
            headers: {
               "Content-Type": "application/json",
                "X-XSRF-TOKEN": getCSRFToken
            },
            body: JSON.stringify({
                "vehicleReg": inputValue.current.value
            })
    })
    .then((res) => {
                if (res.status === 200) {
                    return res.json()
                } else {
                    throw Error("Erro posting data");
                }
                })
                .then((res) => {
                        console.log("Suucessfully send", res)
                })
                .catch((er) => {
                console.log("Error fetching data", er)
        })
}
C# 反应 JS 防伪令牌 ASP.NET-APIC控制器

评论

0赞 pcalkins 10/24/2023
令牌将作为隐藏字段插入到表单中。您可以将整个表单作为 FormData 对象发送(最简单的方法),或者如果您以 JSON 格式发送请求,请从 DOM 中获取它并以这种方式发送。(隐藏字段的名称为“__RequestVerificationToken”...JSON 应匹配)Cookie 会自动发送。(也无需设置标题...
0赞 user2038084 10/24/2023
我相信你所解释的是关于MVC和@Html.AntiForgeryToken()。但是,在 React 中,我很确定我不能使用 @Html.AntiForgeryToken()。
0赞 pcalkins 10/25/2023
您可以检查此线程:stackoverflow.com/questions/69009651/...您每次都需要调用该端点,并在随后的 fetch/POST 中将其用作“__RequestVerificationToken”

答:

0赞 pcalkins 11/3/2023 #1

我不得不将这些位添加到事物 ASP.NET 方面(在启动.cs中):

  services.AddAntiforgery(options =>
  {
      options.HeaderName = "XSRF-TOKEN";
  
  });

然后:

 var antiforgery = app.ApplicationServices.GetRequiredService<IAntiforgery>();

 app.Use((context, next) =>
 {
     var requestPath = context.Request.Path.Value;
  // I only tested one page... you should be able to wild card this or just add each page as needed
     if (string.Equals(requestPath, "/WebAPI/Inventory/EditInventoryItem", StringComparison.OrdinalIgnoreCase))
     {
         var tokenSet = antiforgery.GetAndStoreTokens(context);
         context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
             new CookieOptions { HttpOnly = false });
     }

     return next(context);
 });

另请参阅此处的 MS 文档:https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-7.0#generate-antiforgery-tokens-with-iantiforgery-1

我的前端是 Angular。它有一个组件,您可以使用该组件读取此 cookie 的值“XSRF-TOKEN”,并在每个请求上将其设置为名为“XSRF-TOKEN”的标头。所以你必须做同样的事情。读取 cookie(它设置为 HttpOnly: false,因此您可以执行此操作),然后添加名称为“XSRF-TOKEN”的自定义标头。不要在防伪选项中设置 Cookie 名称。让 ASP.NET 照顾它使用的 cookie。您只需要设置 HeaderName。