How to call a JWT secured APIs with jQuery AJAX [with source codes]

How to call a JWT secured APIs with jQuery AJAX [with source codes]

JWT authentication is a popular standard to secure the Web API. In my last tutorial I explained in full details about ASP.NET Core JWT Authentication and Authorization of Web API, if you haven’t read it make sure you do it now.

ASP.NET Core JWT Bearer Token

When you make an API Call to a JWT protected Web API then you have to add a Bearer token to the Authorization request. This is done in jQuery as shown below.

headers: {
    Authorization: 'Bearer ' + token
}

Let us now call the Web API (that is JWT secured) with jQuery AJAX method. The most important thing to note here is that you have to add the JWT Token value on the header of the HTTP request, and prepend the token’s value with the word – Bearer (note the space at the end of the word).

This tutorial is a part of series called JSON Web Token (JWT) in ASP.NET Core. There are 3 tutorials to master it:

  1. ASP.NET Core JWT Authentication and Authorization of Web API [Detailed]
  2. Implementing JWT Refresh Token in ASP.NET Core MVC
  3. How to call a JWT secured APIs with jQuery AJAX [with source codes]

This is shown in the below code:

$.ajax({
    type: "POST",
    url: "https://localhost:44360/Reservation",
    headers: {
        Authorization: 'Bearer ' + token
    },
    dataType: 'json',
    success: function (result, status, xhr) {
        ShowData(result);
    },
    error: function (xhr, status, error) {
         alert(error);
    }
});
API’s signature is given below

I will call the Web API with jQuery here:

[Route("[controller]")]
[ApiController]
[Authorize]
public class ReservationController : ControllerBase
{
    [HttpGet]
    public IEnumerable<Reservation> Get() {
        // returns a list of reservations
    }
}

Once this feature is created it will work as shown by the below video:

jwt jquery video

Creating full Client JWT Application in jQuery

Make sure you add System.IdentityModel.Tokens.Jwt package from NuGet. This package enables you to create JWT tokens in your application.

Next, create a controller called jQueryApiController.cs in your project and add the following code to it:

public class jQueryApiController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public string Index(string key)
    {
        string tokenString = GenerateJSONWebToken(key);
        return tokenString;
    }

    private string GenerateJSONWebToken(string key)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: "https://www.yogihosting.com",
            audience: "dotnetclient",
            expires: DateTime.Now.AddHours(3),
            signingCredentials: credentials
            );

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

    [HttpPost]
    public IActionResult Reservation([FromBody]List<Reservation> rList)
    {
        return PartialView("Reservation", rList);
    }
}

Explanation: Index action of HTTP Post type will be called by AJAX code on the View. This action method calls the GenerateJSONWebToken(key) method to create the JWT token.

ASP.NET Core JWT Token Expiration

The expiry time of JWT Token is set with “expires” property of JwtSecurityToken class. I have set 3 hours expiry time of the token with the below code.

var token = new JwtSecurityToken(
    ...
    expires: DateTime.Now.AddHours(3),
);

Also note that this is the sliding expiry time.

There is also a Reservation action that accepts a list of reservations (which is the data returned by the API). It then returns a partial view that shows all these reservations.

You will understand how the API call is made when you see the codes on the Views. So, create the Index view whose code is given below:

@{ ViewBag.Title = "Login";}

<h2>Login</h2>

<div id="messageDiv" style="display:none" class="alert alert-danger"></div>
<table class="w-25 table table-striped table-bordered">
    <tbody>
        <tr>
            <td>Security Key</td>
            <td><input type="text" id="key" name="key" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <button id="submit">Submit</button>
            </td>
        </tr>
    </tbody>
</table>

<div id="processDiv" style="display:none">Processing.....</div>
<div id="reservations"></div>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
    $(document).ready(function () {
        $("#submit").click(function (e) {
            $.ajax({
                type: "POST",
                url: "@Url.Action("Index")",
                data: {key: $("#key").val()},
                dataType: "text",
                success: function (result) {
                    if (result != "Error")
                        CallAPI(result);
                    else {
                        $("#messageDiv").show();
                        $("#messageDiv").html("Error");
                    }
                },
                error: function (req, status, error) {
                    alert(error);
                }
            });
        });

        function CallAPI(token) {
            $.ajax({
                type: "GET",
                url: "https://localhost:44314/Reservation",
                headers: {
                    Authorization: 'Bearer ' + token
                },
                dataType: 'json',
                success: function (result, status, xhr) {
                    ShowData(result);
                },
                error: function (xhr, status, error) {
                     alert(error);
                }
            });
        }

        function ShowData(reservations) {
            $.ajax({
                type: "POST",
                contentType: "application/json",
                url: "@Url.Action("Reservation")",
                data: JSON.stringify(reservations),
                success: function (result) {
                    $("#reservations").html(result)
                    $("#messageDiv").hide();
                },
                error: function (req, status, error) {
                    alert(error);
                }
            });
        }

        $(document).ajaxStart(function () {
            $("#processDiv").show();
        });

        $(document).ajaxStop(function () {
            $("#processDiv").hide();
        });
    });
</script>

Explanation: There is an input control for accepting the Security Key / Private Key which is MynameisJamesBond007_MynameisJamesBond007. The screen shot is shown below:

jwt private key

The div with id as reservations will show the reservations returned by the API.

Notice that on the click of the submit button the “Index” action method is called by jQuery. This method will receive the JWT Token, and then on the success callback I am calling another jQuery function named CallAPI and passing the token to it.

The CallAPI() function’s code is given below:

function CallAPI(token) {
    $.ajax({
        ...
    });
}

The CallAPI method makes the API call and adds the JWT Token to the Authorization Header of the request like this:

headers: {
    Authorization: 'Bearer ' + token
},

Notice the space after ‘Bearer ‘ text. On the success callback it calls another function called ShowData(result) whose task is to show the reservations data on the View.

See the ShowData(result) function’s code given below. It makes AJAX call and calls the ‘Reservation’ action method. The reservation action will return a partial view (partial view is bind with the data returned by the API).

function ShowData(reservations) {
    $.ajax({
        type: "POST",
        contentType: "application/json",
        url: "@Url.Action("Reservation")",
        data: JSON.stringify(reservations),
        success: function (result) {
            $("#reservations").html(result)
        },
        error: function (req, status, error) {
            alert(error);
        }
    });
}

Note: inside the success callback we bind the ‘reservations’ div with this data.

Next add the Partial View called Reservation.cshtml inside the Shared folder and add the below code to it.

@model IEnumerable<Reservation>
@{ ViewBag.Title = "All Reservations";}
 
<h2>All Reservations</h2>
<table class="table table-sm table-striped table-bordered m-2">
    <thead><tr><th>ID</th><th>Name</th><th>Start Location</th><th>End Location</th></tr></thead>
    <tbody>
        @if (Model != null)
        {
            foreach (var r in Model)
            {
                <tr>
                    <td>@r.Id</td>
                    <td>@r.Name</td>
                    <td>@r.StartLocation</td>
                    <td>@r.EndLocation</td>
                </tr>
            }
        }
    </tbody>
</table>

Now run your app and open the URL – https://localhost:7154/jQueryApi. Here enter the private key which is “MynameisJamesBond007_MynameisJamesBond007” and you will be see the reservations received from the API call.

JWT Token with Claims

JWT Claims can contain added information to the token. Take for example, a JWT token contains a claim called Name that asserts that the name of the user is “Bobby”. So we can filter the records having person’s name value as “Bobby”.

So, in the Index view, add a new row to the table to contain a new text box for adding name of the person. See the added code shown in highlighted way.

<table class="w-25 table table-striped table-bordered">
    <tbody>
        <tr>
            <td>Security Key</td>
            <td><input type="text" id="key" name="key" /></td>
        </tr>
        <tr>
            <td>Person</td>
            <td><input type="text" id="person" name="person" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <button id="submit">Submit</button>
            </td>
        </tr>
    </tbody>
</table>

This person’s text box value has to be added to the data parameters of the ajax call. So change the submit button’s codes like this:

$("#submit").click(function (e) {
    $.ajax({
        type: "POST",
        url: "@Url.Action("Index")",
        data: { key: $("#key").val(), person: $("#person").val()},
        dataType: "text",
        success: function (result) {
            if (result != "Error")
                CallAPI(result);
            else {
                $("#messageDiv").show();
                $("#messageDiv").html("Error");
            }
        },
        error: function (req, status, error) {
            alert(error);
        }
    });
});

Next, change the controllers code to receive this person’s value.

[HttpPost]
public string Index(string key, string person)
{
    string tokenString = GenerateJSONWebToken(key, person);
    return tokenString;
}

private string GenerateJSONWebToken(string key, string person)
{
    var claims = new[] {
        new Claim("Name", person)
    };

    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: "https://www.yogihosting.com",
        audience: "dotnetclient",
        expires: DateTime.Now.AddHours(3),
        signingCredentials: credentials,
        claims: claims
        );

    return new JwtSecurityTokenHandler().WriteToken(token);
}

The main thing in the above code is that I created a claim called “Name” and providing it with value of the person which the user entered in the text box.

Finally update the API to fetch this claim’s value through the HttpContext.User.Claims class, and then filter out the reservations that matches exactly to the ‘Name’ value assigned on the claim. Check below code:

[HttpGet]
public IEnumerable<Reservation> Get()
{
    var claims = HttpContext.User.Claims;
    return CreateDummyReservations().Where(t => t.Name == claims.FirstOrDefault(c => c.Type == "Name").Value);
}

Check the below video to understand how the filtering works:

jquery jwt video

ASP.NET Core GET JWT Token from Request

We can get the JWT Token which is added to the authorization header of the request by using the code – var jwtToken = Request.Headers[HeaderNames.Authorization];. Here HeaderNames lies in the Microsoft.Net.Http.Headers namespace. Use this code in your controller where you want to extract the token from the request.

public class SomeController : Controller
{
    public IActionResult Index()
    {
        var jwtToken = Request.Headers[HeaderNames.Authorization];
        return View();
    }
}

You can download the full codes of this tutorial from the below link:

Download

Conclusion

I hope you enjoyed creating this JWT feature with jQuery. Please share this tutorial with your friends to. Thank you!

SHARE THIS ARTICLE

  • linkedin
  • reddit
yogihosting

ABOUT THE AUTHOR

I hope you enjoyed reading this tutorial. If it helped you then consider buying a cup of coffee for me. This will help me in writing more such good tutorials for the readers. Thank you. Buy Me A Coffee donate

Leave a Reply

Your email address will not be published. Required fields are marked *