Skip to content

Commit

Permalink
Add Endpoint for antiforgerySnippet.js for more flexibility.
Browse files Browse the repository at this point in the history
  • Loading branch information
khalidabuhakmeh committed May 26, 2023
1 parent 74d56f6 commit c526ae6
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 7 deletions.
31 changes: 31 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,37 @@ This html helper will result in a `<script>` tag along with the previously menti

Note that if the `hx-[get|post|put]` attribute is on a `<form ..>` tag, the ASP.NET Tag Helpers will add the Anti-forgery Token as an `input` element and you do not need to further configure your requests as above. You could also use [`hx-include`](https://htmx.org/attributes/hx-include/) pointing to a form, but this all comes down to a matter of preference.

Additionally, and **the recommended approach** is to use the `HtmxAntiforgeryScriptEndpoint`, which will let you map the JavaScript file to a specific endpoint, and by default it will be `_htmx/antiforgery.js`.

```c#
app.UseAuthorization();
// registered here
app.MapHtmxAntiforgeryScript();
app.MapRazorPages();
app.MapControllers();
```

You can now configure this endpoint with caching, authentication, etc. More importantly, you can use the script in your `head` tag now by applying the `defer` tag, which is preferred to having JavaScript at the end of a `body` element.

```html
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta
name="htmx-config"
historyCacheSize="20"
indicatorClass="htmx-indicator"
includeAspNetAntiforgeryToken="true"/>
<title>@ViewData["Title"] - Htmx.Sample</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
<script src="~/lib/jquery/dist/jquery.min.js" defer></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js" defer></script>
<script src="https://unpkg.com/htmx.org@@1.9.2" defer></script>
<!-- this uses the static value in a script tag -->
<script src="@HtmxAntiforgeryScriptEndpoints.Path" defer></script>
</head>
```

## License

Expand Down
2 changes: 2 additions & 0 deletions src/Htmx.TagHelpers/HtmlExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public static class HtmlExtensions
/// </summary>
/// <remarks>
/// Note: This includes wrapping script tags.To get the JavaScript string use <see cref="HtmxSnippets.AntiforgeryJavaScript">HtmxSnippets.AntiforgeryJavaScript</see>.
///
/// You may also want to consider using the <see cref="HtmxAntiforgeryScriptEndpoints"/> instead of this approach.
/// </remarks>
/// <param name="helper">An instance of the HTML Helper interface</param>
/// <returns>HTML Content with JavaScript tag</returns>
Expand Down
37 changes: 37 additions & 0 deletions src/Htmx.TagHelpers/HtmxAntiforgeryScriptEndpoints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace Htmx.TagHelpers;

public static class HtmxAntiforgeryScriptEndpoints
{
/// <summary>
/// The path to the antiforgery script that is used from HTML
/// </summary>
public static string Path { get; private set; } = "_htmx/antiforgery.js";

/// <summary>
/// Register an endpoint that responds with the HTMX antiforgery script.<br/>
/// IMPORTANT: Remember to add the following script tag to your _Layout.cshtml or Razor view:
/// <![CDATA[
/// <script src="@HtmxAntiforgeryScriptEndpoints.Path" defer></script>
/// ]]>
/// </summary>
/// <param name="builder">Endpoint builder</param>
/// <param name="path">The path to the antiforgery script</param>
/// <returns>The registered endpoint (Use <seealso cref="Path"/> to reference endpoint)</returns>
public static IEndpointConventionBuilder MapHtmxAntiforgeryScript(
this IEndpointRouteBuilder builder,
string? path = null)
{
// set Path globally for access
Path = path ?? Path;

return builder.MapGet(Path, async ctx =>
{
ctx.Response.ContentType = "text/javascript";
await ctx.Response.WriteAsync(HtmxSnippets.AntiforgeryJavaScript);
});
}
}
2 changes: 1 addition & 1 deletion src/Htmx.TagHelpers/JavaScript/antiforgerySnippet.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ if (!document.body.attributes.__htmx_antiforgery) {
if (httpVerb === 'GET') return;
let antiForgery = htmx.config.antiForgery;
if (antiForgery) {
// already specified on form, short circuit
// already specified on the form, short circuit
if (evt.detail.parameters[antiForgery.formFieldName])
return;

Expand Down
9 changes: 4 additions & 5 deletions test/Sample/Pages/Shared/_Layout.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<title>@ViewData["Title"] - Htmx.Sample</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
<script src="~/lib/jquery/dist/jquery.min.js" defer></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js" defer></script>
<script src="https://unpkg.com/htmx.org@@1.9.2" defer></script>
<script src="@HtmxAntiforgeryScriptEndpoints.Path" defer></script>
</head>
<body>
<header>
Expand Down Expand Up @@ -47,11 +51,6 @@
</div>
</footer>

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://unpkg.com/htmx.org@@1.9.2"></script>
@Html.HtmxAntiforgeryScript()

@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
4 changes: 3 additions & 1 deletion test/Sample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Htmx.TagHelpers;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
Expand All @@ -20,7 +22,7 @@
app.UseRouting();

app.UseAuthorization();

app.MapHtmxAntiforgeryScript();
app.MapRazorPages();
app.MapControllers();

Expand Down

0 comments on commit c526ae6

Please sign in to comment.