Open Rick-Anderson opened 1 year ago
I think this works @Rick-Anderson
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.MapGet("/antiforgery", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.html("/todo", token), "text/html");
});
app.MapGet("/non-antiforgery", () =>
{
Console.WriteLine("nonantiforgery");
return Results.Content(MyHtml.html("/todo2"), "text/html");
});
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
app.Run();
class Todo
{
public required string Name { get; set; }
public bool IsCompleted { get; set; }
public DateTime DueDate { get; set; }
}
public static class MyHtml
{
public static string html(string action, AntiforgeryTokenSet token = null)
{
var forgeryInputField = token is null ?
"" : generateTokenField(token);
return $"""
<html><body>
<form action="{action}" method="POST" enctype="multipart/form-data">
{forgeryInputField}
<input type="text" name="name" />
<input type="date" name="dueDate" />
<input type="checkbox" name="isCompleted" />
<input type="submit" />
</form>
</body></html>
""";
}
public static string generateTokenField(AntiforgeryTokenSet token) => $"""
<input name="{token.FormFieldName}"
type="hidden" value="{token.RequestToken}" />
""";
}
See Antiforgery integration for minimal APIs
and this sample
In this code I pass in the action so
Can use the same HTML when they pass in the action arg.
Is there a clean way to do this to pass in an arg for
Maybe that makes things too messy. Perhaps I should duplicate most of the HTML and not get the HTML from a method while passing the action.
Works, but I'm not sure it's an improvement. There's no way to pass in a null token.
@sammychinedu2ky @david-acker
cc @guardrex