Search code examples
jqueryajaxasp.net-web-api2asp.net-identity

Get/Post/Put methods on current logged in user properties - ASP.NET Web API 2 with ajax request jquery


So everything works fine I am just not sure if this is the way I am supposed to do it. Here is an example for changing the shipping address on the currently logged in user.
This is the controller i made:

    [Route("addShippingAdress")]
    [HttpPut] 
    public void addAddress([FromBody] string newShippingAdress)
    {
       string userId = User.Identity.GetUserId();
       db.Users.Find(userId).ShippingAdress = newShippingAdress;
       db.SaveChanges();
    }

This is the Ajax Request for changing the shipping address:

    $.ajax({
            url: 'addShippingAdress',
            method: 'PUT', 
            contentType: 'application/json',
            headers: {
                'Authorization': 'Bearer '
                    + sessionStorage.getItem("accessToken")
            },
            dataType: "text",
            data: JSON.stringify("some new adress"),
            success: function (data) {
            },
            error: function (data) {
            }
        });

and this is the Ajax request that I use to Log In:

$.ajax({
                url: '/token',
                method: 'POST',
                contentType: 'application/json',
                data: {
                    username: $('#txtUserName').val(),
                    password: $('#txtPassword').val(),
                    grant_type: 'password'
                },
                success: function (response) {
                    sessionStorage.setItem("accessToken", response.access_token);
                    sessionStorage.setItem("userName", response.userName);
                    window.location.href = "Data.html";
                },
                error: function (data) {
                console.log(data)
                }
            });

So to be more specific, in future when I want to get some properties on the logged in user, or change some of the properties on the logged in user like the shipping address in the example i gave you, is this the way I do it? Do i need to send the access token with every Ajax request like this:

...
headers: {
'Authorization': 'Bearer '
+ sessionStorage.getItem("accessToken")
},
...

for every controller that i want to use for the logged in user and then find the logged in user like:

 string userId = User.Identity.GetUserId();
 var loggedInUser = db.Users.Find(userId);
 loggedInUser... // some logic here

Is this the correct way to do it? If so where does the controller reads the access token that I send in the header of the Ajax request? When i send the shipping address in the body the controller can read it with help of the [FromBody] attribute like this:

public void addAddress([FromBody] string newShippingAdress)

But where does it read the access token I send in the Header? I am novice so please have some patience and understanding. Have a nice day!


Solution

  • In your API project, create a custom authentication filter as follows:

    Create a class TokenAuthenticationFilterAttribute which inherits from System.Web.Http.Filters.AuthorizationFilterAttribute class.

    Override the OnAuthorization method as follows

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        // Read the authorization header from the request
        var auth = actionContext.Request.Headers.Authorization;
    
        if(auth != null && auth.Scheme.ToLower().Equals("bearer", StringComparison.InvariantCultureIgnoreCase))
        {
            // Validate the header value against database
    
            // If validation fails, send appropriate response
            actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        }
    }
    

    Use this filter on your action methods or controller as follows:

    [Route("addShippingAdress")]
    [HttpPut] 
    [TokenAuthenticationFilter]
    public void addAddress([FromBody] string newShippingAdress)
    {
        string userId = User.Identity.GetUserId();
        db.Users.Find(userId).ShippingAdress = newShippingAdress;
        db.SaveChanges();
    }