ASP.NET MVC6 Identity Part 4 – AJAX Authentication

In the last few articles, I’ve covered the following:

  1. Creating an ASP.NET Identity Database
  2. Data Annotations and Custom Validators for Models
  3. A WebAPI Authenticator
  4. An ECMAScript 6 Modal Dialog

Four articles and I still haven’t logged in to my application. Today that is going to change because I’m writing the front-end AJAX code to do the authentication handling.

Doing AJAX Request Promises

Some months ago, I wrote about doing ECMAScript 6 HTTP Requests with Promises. I have a library for that now and I’m going to use it in this project. It’s stored in Static/js/ajax.js. Let’s walk through it:

 * Routines for dealing with AJAX
/*eslint no-console:0 */
"use strict";

function callAjax(method, url, query, body, headers) {
    console.debug("[callAjax] method=%s url=%s query=%o body=%o headers=%o", method, url, query, body, headers);

One method is all it takes to handle all the AJAX functionality. Note that I’m using an eslint directive at the top to say “I’m going to use console statements, so be quiet about it”. When I change over to a non-debug version, I’ll remove that line and all the console statements.

    let uri = url;
    if (query != null) {
        console.debug("[callAjax] query has been specified - processing");
        if (typeof query === "object") {
            console.debug("[callAjax] query is an object");
            let qs = Object.keys(query).map(k => encodeURIComponent(k) + "=" + encodeURIComponent(query[k]));
            uri = uri + "?" + qs.join("&");
        else if (typeof query === "string") {
            // Assume the query string is already encoded
            console.debug("[callAjax] query is a string (adding unmodified)");
            uri = uri + "?" + query;
        console.debug("[callAjax] New URI is %s", uri);

The next block turns an object, say {"Email":"foo","Password":"bar"} into the appropriate URI encoded query string Email=foo&Password=bar. If the function got passed a string instead of an object, it just uses the string that is provided. It constructs the new URI based on this query string.

    let requestBody = "";
    if (body != null) {
        console.debug("[callAjax] Body has been specified - processing");
        if (typeof body === "object") {
            console.debug("[callAjax] body is an object");
            requestBody = JSON.stringify(body);
            headers["Content-type"] = "application/json";
        } else if (typeof body === "string") {
            console.debug("[callAjax] body is a string (adding unmodified)");
            requestBody = body;
        console.debug("[callAjax] BODY = %s", requestBody);

Next up is the body – used in POST and PUT REST calls. I’m using the JSON methods that are built into pretty much every browser these days. If the method is passed an object, I turn it into JSON and then update the headers to include a Content-type header. As with the query parameters, if I pass a string then I just include it and assume the caller knows what they are doing.

    return new Promise(function (resolve, reject) {
        console.debug("[callAjax] Creating new XMLHttpRequest");
        let request = new XMLHttpRequest();
        console.debug("[callAjax] Open a %s request to %s", method, uri);, uri);
        for (var p in headers) {
            if (headers.hasOwnProperty(p)) {
                console.debug("[callAjax] Add header %s: %s", p, headers[p]);
                request.setRequestHeader(p, headers[p]);

        console.debug("[callAjax] Set resolve to the onload object");
        request.onload = function() {

        console.debug("[callAjax] Set reject to the onerror object");
        request.onerror = function() {

        console.debug("[callAjax] Send requested body");

Finally, I construct the XMLHttpRequest wrapped in a promise. Since I expect that different codes are going to get returned, I’m not going to assume that 200 is the only valid code. I did this in the prior version of the library. Instead I say “success is when the server responds and failure is when the server does not response”.

 * Helper Functions for each method
function ajaxDelete(url, query, headers) { //eslint-disable-line no-unused-vars
    return callAjax("DELETE", url, query || {}, null, headers || {});

function ajaxGet(url, query, headers) { //eslint-disable-line no-unused-vars
    return callAjax("GET", url, query || {}, null, headers || {});

function ajaxPost(url, args, headers) { //eslint-disable-line no-unused-vars
    return callAjax("POST", url, null, args, headers || {});

function ajaxPut(url, args, headers) { //eslint-disable-line no-unused-vars
    return callAjax("PUT", url, null, args, headers || {});

export { ajaxDelete, ajaxGet, ajaxPost, ajaxPut };

Finally, I set up a number of functions that send the right arguments to the callAjax() method. GET and DELETE calls use a query method. POST and PUT calls use a body method. This way every method uses the same arguments and the right format gets sent to the backend.

Feel free to co-opt this library file for yourself.

Calling the WebAPI

Now, how do we use this library? In the last article I created a LoginModal class for handling the login modal. Let’s take a look at the new code:

 * Handler for the Login Modal
/*eslint no-console:0 */
"use strict";

import { ajaxPost } from "./ajax";

class LoginModal {
     * Constructor - store the ID that activates us and then
     * wire up the activator.
    constructor(activatorEl, modalEl) {
        // Store all the elements for later
        this.activator = activatorEl;
        this.modal = modalEl;
        this.modalClose = modalEl.querySelector(".modalClose");
        this.submitButton = modalEl.querySelector("button#loginButton");

        // Make the activator cursor a pointer to show it is clickable = "pointer";

        // Wire up the click event handlers for the activator and modal close
        this.activator.addEventListener("click", (e) => { return this.activate(e); });
        this.modalClose.addEventListener("click", (e) => { return this.close(e); });

        // Wire up the submission button for the form
        this.submitButton.addEventListener("click", (e) => { return this.submit(e); });

        // Ensure the modal is hidden = "none"; = "0";


As with the AJAX library, I’m using the eslint directive to disable complaints about the console. I then bring in the ajaxPost method (the only one I need in this file) from the AJAX library above.

In the constructor, I’ve added information about the submit button and wired up an event handler for when the user clicks on the submit button.

     * Someone hit the submit button.
    submit(e) {
        let modal = this.modal,
            submitButton = this.submitButton,
            spinner = "<i class='fa fa-spinner fa-pulse'></i> ",
            submitContent = this.submitButton.innerHTML;

        // Deactivate the form
        submitButton.disabled = true;
        submitButton.innerHTML = spinner + submitContent;

The first thing we do when going into the submit button event handler is to deactivate the form. Sometimes you will have a slow link – you don’t want someone clicking repeatedly on the submit button and having that kick off tons of requests to the backend – the idea is to reduce the load on the backend, not increase it. To indicate that the form is busy, I’ve added a spinner to the button content.

        // Validation goes here (eventually)

        // Submit AJAX Request
        let requestArgs = {
            "Email": this.modal.querySelector("input[name=Email]").value,
            "Password": this.modal.querySelector("input[name=Password]").value
        console.debug("[LoginModal#submit] requestArgs = %o", requestArgs);

I’m not doing client side validation (yet). I’ll get to it. From the WebAPI work, I know that my request has to be a JSON request with the Email and Password fields, so I need to construct an object that I can pass along. Next step is the actual AJAX call:

        ajaxPost("/api/login", requestArgs)
            .catch(function(error) {
                console.error("[LoginModal#submit] Error in AJAX Call to /api/login: %o", error);
            .then(function (response) {
                console.debug("[LoginModal#submit] AJAX Call to /api/login: Response = %o", response);
                if (response.status === 200) {
                    // We got a 200 Success back, so refresh the page
                } else if (response.status === 400) {
                    let r = JSON.parse(response.response);

                    // If there were errors, then add them to the appropriate areas on
                    // the form.  If there weren't errors, make sure those same areas
                    // don't have errors (handles multiple submissions)
                    if (r[""]) {
                        modal.querySelector("#errorForSignInModal").innerHTML = r[""][0];
                    } else {
                        modal.querySelector("#errorForSignInModal").innerHTML = "";
                    if (r.Email) {
                        modal.querySelector("#errorForEmail").innerHTML = r.Email[0];
                    } else {
                        modal.querySelector("#errorForEmail").innerHTML = "";
                    if (r.Password) {
                        modal.querySelector("#errorForPassword").innerHTML = r.Password[0];
                    } else {
                        modal.querySelector("#errorForPassword").innerHTML = "";

                    // Re-activate the form
                    submitButton.innerHTML = submitContent;
                    submitButton.disabled = false;

        return false;

If you remember from my discussion on ES6 Promises, I can catch errors and handle responses asynchronously. The catch statement says “there is an error” – right now, I’m just logging the error in the console and not re-activating the form. This isn’t very friendly and I should probably do something about that.

In the then clause, I handle the response. There are two possible responses from the WebAPI – a 200 Success with a few cookies or a 400 Bad Request with some JSON. If the response is Success then the browser already knows about the cookies and all I have to do is reload the page.

If the response is a 400 Bad Request, then I turn the JSON response into an object and look for things I’m interested in, placing the response in prepared locations in the modal dialog. Once that is done, I restore the button content (which removes the spinner) and re-enable the submit button.

Running the Code

If you run this code and click on the Sign In button, the modal will pop up. At this point you can bring up the F12 Developer Tools and hop over to the Console window. Enter some information and see what comes up:


I’ve added a number of console.debug statements so you can see what is happening. You can also click on any of the objects with a triangle beside them to see the actual contents. Here I’ve entered “admin@” as the username, so I’m expecting a 400 Bad Request, which is exactly what I get.

Problems Still to be Solved

There are two problems to be solved. Firstly, users like to be able to press Enter in the text boxes to submit the form. I’m not capturing key presses within the form so I can’t emulate that functionality. Right now, the only submission possibility is clicking on the button.

Secondly, if there is an error in transmission then there is no indication. The form will continue to spin. This is an easy fix and I’ll do it before I check in the code.

Finally, I don’t do any client-side validation. I leave the validation to the server-side. This means that there are extra round-trips happening when it’s not really necessary. I’ll fix that in the next article.