2

I want to implement JWT Authentication in react js using web api.

I had created the JWT Authentication in web api.

It worked totally fine on Postman as I tested it.

When I am using it with react js the API is being hitted.

Now the problem is how do I send the token to react js and how do I fetch the token in react js

This is my Login Controller in web api

using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Web;
using System.Web.Http;
using System.Web.Http.Cors;
using WEBAPI_JWT_Authentication.Models;


namespace WEBAPI_JWT_Authentication.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class LoginController : ApiController
    {
        [HttpPost]
        public IHttpActionResult Authenticate([FromBody] LoginRequest login)
        {
            var loginResponse = new LoginResponse { };
            LoginRequest loginrequest = new LoginRequest { };
            loginrequest.Username = login.Username.ToLower();
            loginrequest.Password = login.Password;

            IHttpActionResult response;
            HttpResponseMessage responseMsg = new HttpResponseMessage();
            bool isUsernamePasswordValid = false;       

            if(login != null)
            isUsernamePasswordValid=loginrequest.Password=="test" ? true:false;
            // if credentials are valid
            if (isUsernamePasswordValid)
            {
                string token = createToken(loginrequest.Username);
                var responseJSON = token;
                //return the token
                return Ok(responseJSON);
            }
            else
            {
                // if credentials are not valid send unauthorized status code in response
                loginResponse.responseMsg.StatusCode = HttpStatusCode.Unauthorized;
                response = ResponseMessage(loginResponse.responseMsg);
                return response;
            }
        }

        private string createToken(string username)
        {
            //Set issued at date
            DateTime issuedAt = DateTime.UtcNow;
            //set the time when it expires
            DateTime expires = DateTime.UtcNow.AddDays(7);

            //http://stackoverflow.com/questions/18223868/how-to-encrypt-jwt-security-token
            var tokenHandler = new JwtSecurityTokenHandler();

            //create a identity and add claims to the user which we want to log in
            ClaimsIdentity claimsIdentity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.Name, username)                
            });

            const string sec = "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1";
            var now = DateTime.UtcNow;
            var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
            var signingCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey,Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature);


            //create the jwt
            var token =
                (JwtSecurityToken)
                    tokenHandler.CreateJwtSecurityToken(issuer:"http://localhost:50191",audience:"http://localhost:50191",
                        subject: claimsIdentity, notBefore: issuedAt, expires: expires, signingCredentials: signingCredentials);
            var tokenString = tokenHandler.WriteToken(token);

            return tokenString;
        }
    }
}

This is where I am fetching the token in react js

function login(username, password) {
    return fetch(`${API_URL}/Login`, {username, passowrd})
        .then(response => {
            debugger;
            if (!response.ok) {
                return response;
            }

            return response.json();
        })
        .then(user => {
            debugger;
            // login successful if there's a jwt token in the response
            if (user && user.token) {
                // store user details and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('user', JSON.stringify(user));
            }

            return user;
        });
}

Rather than this data if anyone knows how to send token to react js and how to fetch that token in react js, please do tell.

Lawraoke
  • 540
  • 5
  • 25
Karan Patokar
  • 465
  • 1
  • 8
  • 21
  • I think your problem is that you don't do an HTTP post with the fetch. You need to add method:'POST' in the fetch options – J.Loscos Apr 18 '18 at 11:16

1 Answers1

0

The way I do is to create a Response class

public class Response
{
    public string Status { get; set; }
    public string Message { get; set; }
    public object Token { get; set; }
}

Depending on your need what you want to define in this class, for my cases, Status and Message is used to update progress status to front end.

You store your tokendictionary in class Response, and return it to the function. Lets say:

[HttpPost]
        public IHttpActionResult Authenticate([FromBody] LoginRequest login)
        {
            var loginResponse = new LoginResponse { };
            LoginRequest loginrequest = new LoginRequest { };
            loginrequest.Username = login.Username.ToLower();
            loginrequest.Password = login.Password;
        IHttpActionResult response;
        HttpResponseMessage responseMsg = new HttpResponseMessage();
        bool isUsernamePasswordValid = false;       

        if(login != null)
        isUsernamePasswordValid=loginrequest.Password=="test" ? true:false;
        // if credentials are valid
        if (isUsernamePasswordValid)
        {
            string token = createToken(loginrequest.Username);
            Response Resp = new Response
            {
                Status = "Success",
                Message = "User Login Successfully Change the Status Message here",
                Token = tokenDictonary, //where you return token
            };
            return 
        }
        else
        {
            // if credentials are not valid send unauthorized status code in response
            loginResponse.responseMsg.StatusCode = HttpStatusCode.Unauthorized;
            response = ResponseMessage(loginResponse.responseMsg);
            return response;
        }
    }

and in your front end, you fetch your api. I show you axios example

axios.post('http://yoururl', {
      Token: this.state.Token,
    })
      .then(result => {
        if (result.data.Status === 'Success') {
          localStorage.setItem('Nameyourvariablehere', result.data.Token.tokentype);
// generate more if your token has more field

and then you are able to check your localStorage via getItem and setItem, I believe you know what to do for the following steps

Actually the way you create token is different from mine, I kind of follow this example.

Lawraoke
  • 540
  • 5
  • 25