/// <summary> Refreshes jwt token</summary> public async Task <UserJwtResponseDto> RefreshJwtToken(RefreshJwtTokenDto refreshJwtTokenDto) { var validatedToken = _jwtAuthService.GetPrincipleFromToken(refreshJwtTokenDto.Token); if (validatedToken == null) { throw new AuthenticationException("Invalid token"); } var tokenExpireDateUnix = long.Parse(validatedToken.Claims.Single(x => x.Type == JwtRegisteredClaimNames.Exp).Value); var tokenExpireDateUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) .AddSeconds(tokenExpireDateUnix); if (tokenExpireDateUtc > DateTime.UtcNow) { throw new AuthenticationException("Token has not expired yet"); } // get token id var jti = validatedToken.Claims.Single(x => x.Type == JwtRegisteredClaimNames.Jti).Value; var storedRefreshToken = await _context.RefreshTokens .FirstOrDefaultAsync(x => x.Token == refreshJwtTokenDto.RefreshToken); if (storedRefreshToken == null) { throw new AuthenticationException("Passed refresh token does not exist"); } if (DateTime.UtcNow > storedRefreshToken.ExpireDate) { throw new AuthenticationException("Passed refresh token has expired"); } if (storedRefreshToken.Invalidated) { throw new AuthenticationException("Passed refresh token is invalidated"); } if (storedRefreshToken.IsUsed) { throw new AuthenticationException("Passed refresh token has been used"); } if (storedRefreshToken.JwtId != jti) { throw new AuthenticationException("Passed refresh token does not match given JWT"); } try { storedRefreshToken.IsUsed = true; await _context.SaveChangesAsync(); } catch (DbUpdateException ex) { throw new AppException("An error occurred during refreshing token", ex); } var userId = validatedToken.Claims.Single(x => x.Type == ClaimTypes.NameIdentifier).Value; var user = await GetById(userId); var userResponseDto = _mapper.Map <UserJwtResponseDto>(user); var jwtTokenDto = await _jwtAuthService.GetToken(user); userResponseDto.Token = jwtTokenDto.Token; userResponseDto.RefreshToken = jwtTokenDto.RefreshToken; return(userResponseDto); }