Hasan A Yousef Hasan A Yousef - 29 days ago 8
C# Question

Cancelling / Preventing route navigation in Dot Net Core

I've a typical API in C# Dot Net Core, where a list of orders is returned back upon receiving the

ajax
request of
$.getJSON(apiUrl)
as below:

$.getJSON("api/Orders")
.done(function (data) {
// On success, 'data' contains a list of products.
$.each(data, function (key, item) {
// Add a list item for the product.
$('<li>', { text: formatItem(item) }).appendTo($('#products'));
});
});


My controller is simply like below:

public class OrdersController
{
[HttpGet("api/Orders")]
public object Orders()
{
return new
{
.
.
};
}
}


The above is fine with me.

My problem is, if the user entered in the browser a url like:
http://localhost/api/Orders
he will be getting th same output, which I want to prevent.

i.e. I need to allow the access to my API through
ajax
only, and need to prevent (or cancel or redirect) it if received through
navigation
in the browser address line.

Thanks

Answer

Thanks for all the hits given, I solved it by the creating a middleware as below:

  1. Created a folder Middleware
  2. Inside this new folder, I created 2 files MiddleWalewareExtensions.cs and RequestHeaderMiddleware.cs

  3. The MiddleWalewareExtensions.cs is the one defining all the middlewares we are having, in this example it is just one, the code is:

    using Microsoft.AspNetCore.Builder;    // for IApplicationBuilder
    namespace myApp.Middleware
    {
       public static class MiddlewareExtensions  
    {
       public static IApplicationBuilder UseRequestHeaderMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<RequestHeaderMiddleware>();
    }
    ... here you can define others
    

    } }

  4. The RequestHeaderMiddleware is the middleware that checks if url contains the word api it is executed only if the header contains user-key and this key is a valid one, otherwise an error is returned. if the link does not contains the api word it is executed without a need of a user key.

     using Microsoft.AspNetCore.Http;
     using System.Threading.Tasks;
    
     namespace myApp.Middleware
     {
     public class RequestHeaderMiddleware  
     {
     private readonly RequestDelegate _next;
     public RequestHeaderMiddleware(RequestDelegate next)
     {
         _next = next;
     }
    
    public async Task Invoke(HttpContext context)
    {
        string url = context.Request.Path;
    
        if (url.Contains("api") && !context.Request.Headers.Keys.Contains("user-key"))
        {
            context.Response.StatusCode = 400; //Bad Request                
            await context.Response.WriteAsync("You need a user key to be able to access this API..");
            return;
        }
        else
            {
                if(context.Request.Headers["user-key"] != "28236d8ec201df516d0f6472d516d72d")
                {
                    context.Response.StatusCode = 401; //UnAuthorized
                    await context.Response.WriteAsync("Invalid User Key");
                    return;
                }
            }
    
        await _next.Invoke(context);
       }
      }
     } 
    
    1. In the Startup.cs file add using myApp.Middleware; then:

      public void Configure(IApplicationBuilder app) 
      {
         app.UseRequestHeaderMiddleware();
         app.UseMvc(routes =>
         {
          routes.MapRoute(
              name: "default",
              template: "{controller=Home}/{action=Index}/{id?}");
         });
      
    2. In the JavaScript client app add the required header to the xmlhttp like:

         xmlhttp.setRequestHeader("user-key", "28236d8ec201df516d0f6472d516d72d");