William Leme

Software Engineer

Securing your jwt in a js app (video tutorial - part 1)

Posted at — Apr 8, 2020

Are you wondering where to store a jwt token in your js app ? In this video tutorial I explain where and how to store a jwt token in order to avoid XSS attacks.

Download source code https://github.com/wleme/JwtInJsApps

Code Snippet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
	//file: startup.cs
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
		//Setup your asp.net core application to use token authentication
            services.AddAuthentication()
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
        {
            ValidIssuer = Configuration["Auth:Issuer"],
            ValidAudience = Configuration["Auth:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Auth:Key"]))
        };
    });
            
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
			//Create custom middleware that retrieves the jwt token from the cookie. 
			//It has to come before UseAuthentication and UseAuthorization.
            app.Use(async (context, next) =>
            {
                var jwt = context.Request.Cookies[Support.Constants.Auth.JwtCookieName];
                if (jwt != null)
                    context.Request.Headers.Add("Authorization", "Bearer " + jwt);
                await next();
            });

            app.UseAuthentication();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//file AuthController.cs
	[ApiController]
    [Route("[CONTROLLER]")]
    public class AuthController : ControllerBase
    {
        private readonly IConfiguration config;

        public AuthController(IConfiguration config)
        {
            this.config = config;
        }


        [HttpPost]
        [Route("login")]
        public IActionResult Login(AuthLoginDto dto)
        {
            if (dto.UserName == "username" && dto.Password == "password")
            {
                var claims = new List<Claim>()
                {
                    new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
                    new Claim(JwtRegisteredClaimNames.UniqueName,dto.UserName),
                };

                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["Auth:Key"]));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                var token= new JwtSecurityToken(
                    config["Auth:Issuer"],
                    config["Auth:Audience"],
                    claims,
                    expires: DateTime.UtcNow.AddHours(1),
                    signingCredentials: creds
                    );


                var results = new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token),
                    expirationUtc = token.ValidTo
                };
				//Create a cookie based on a custom request header sent by the client
                if (Request.Headers.TryGetValue("X-Return-Cookie", out var returnCookie))
                {
                    if (returnCookie.ToString().ToUpper() == true.ToString().ToUpper())
                    {
                        Response.Cookies.Append(Support.Constants.Auth.JwtCookieName, results.token, new Microsoft.AspNetCore.Http.CookieOptions()
                        {
                            HttpOnly = true,
                            Expires = dto.RememberMe ? results.expirationUtc : (DateTime?)null,
                            Secure = true
                        });
                    }
                }

                return Created("", results);
            }

            return BadRequest("Cannot login");
        }
    }