0

Environment: ASP.NET Core 6.0, Razor Pages

Authentication:

The users log in, and their access token (Bearer jwt) is stored in Session storage.

The problem:

I want to display an array of objects that a request gives me. These objects have a part that has to be queried separately for each of them from the backend. For presentation purposes, I want to display them on the same page, but I do not want to query them before the page loads, because that is slow.

So the question is, how to access HttpClient (or the service that uses HttpClient and handles requests) from jQuery? My current idea is to pass the Bearer token to the partials, that way it can be accessed from them, and to go with an XMLHttpRequest. Are there any better solutions to populate these dropdowns on demand?

Index.cshtml

@page
@model IndexModel
@foreach (var part in Model.Parts)
{
    <partial name="_PartPartial" model="new { PartData = part, Id = @Model.Id, Bearer = Bearer }" />
}

Index.cshtml.cs

public class IndexModel : PageModel
{
    public List<PartModel> Parts;
    public string Id;

    public async Task<IActionResult> OnGetAsync(string Id)
    {
        // Query Parts from endpoint...
        return Page();
    }
}

_PartPartial.cshtml

@model dynamic

<div class="card">
    <div class="card-header">
        <button type="button" class="btn" data-bs-toggle="collapse" data-bs-target="#partContent_@Model.PartData.partId"
                aria-expanded="false" aria-controls="partContent_@Model.PartData.partId" data-id="@Model.PartData.partId" onclick="queryInnerData(this);">
            @Model.PartData.DisplayName
        </button>
    </div>
    <div class="collapse" id="partContent_@Model.PartData.partId">
        <div class="card card-body">
            <div id="innerData_@Model.PartData.partId"></div>
        </div>
    </div>
</div>

<script type="text/javascript">
    function queryInnerData(sender)
    {
        // This is the part where I am stuck. How do I access the Bearer
    }

</script>

I have tried creating a page that does an HttpRequest and returns a JsonResult in its OnGet method. This works, but exposes the raw data to the outside world as well, so I would rather not go with this solution.

ato
  • 1
  • 1
    What do you mean by `HttpClient` in the first place? And how is jQuery involved? If you want to call any URL from JavaScript you use either JavaScript's built-in [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) or a library. If you want to use jQuery's `$.ajax` you can just do it although its functionality is now available in JS itself. The call will include the browser's cookies, including any authentication cookies. If your endpoints require authentication only authenticated users will be able to make that GET call – Panagiotis Kanavos Nov 18 '22 at 10:02
  • `XMLHttpRequest` aka `$post()` or `$get` (or nowadays - Fetch API) is the standard way to go. You can't, however, completely block the exposure of the raw data endpoint from the outside - you can only put it behind the same authentication you use for the page itself. If you worry about CSRF attacks, you might also want to look at this article: https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-7.0 – Sergey Kudriavtsev Nov 18 '22 at 10:03
  • Is the real question how to authenticate your single page application? That's where JWTs come in. Once you have a JWT you can include it as a header in the `fetch` call – Panagiotis Kanavos Nov 18 '22 at 10:04
  • _"If your endpoints require authentication only authenticated users will be able to make that GET call"_, I get that, but I want to hide raw output of the endpoint from them. I don't them to see how the backend returns the data. – ato Nov 18 '22 at 10:25
  • For authentication I am not using cookies, but the Session storage that I access with HttpContext. When I save jwt it looks the following: `HttpContext.Session.SetString("access_token", responseObject.access_token)` – ato Nov 18 '22 at 10:26
  • _"Is the real question how to authenticate your single page application? "_ Well yes, but actually no. Technically it acts like an SPA, but it uses ASP.NET Core 6.0's Razor pages. – ato Nov 18 '22 at 10:28
  • If you don't want the user to see the raw output from the endpoints, you should not call them directly using AJAX. You should get the data using server-side code. Get your AJAX calls to call named handlers that return PartialViewResult objects consisting of your partials being populated with the data on the server. https://www.learnrazorpages.com/razor-pages/ajax/partial-update – Mike Brind Nov 18 '22 at 12:19
  • Here's how to add a bearer token to a jQuery AJAX call: https://stackoverflow.com/questions/51506579/sending-authorization-token-bearer-through-javascript – Mike Brind Nov 18 '22 at 12:21
  • @MikeBrind Thank you, that is just what I am looking for (the first one)! – ato Nov 18 '22 at 12:38

0 Answers0