public string GenerateRefreshToken(AuthenticationTicket ticket, string userName, string accessToken)
        {
            var context = new AuthenticationTokenCreateContext(_owinContext, AuthMiddleware.AuthBearerAuthenticationOptions.AccessTokenFormat, ticket);
            var token   = new RefreshTokenRecord
            {
                Token      = accessToken,
                UserName   = userName,
                IssuedUtc  = DateTime.UtcNow,
                ExpiresUtc = DateTime.UtcNow.AddDays(1)
            };

            context.Ticket.Properties.IssuedUtc  = DateTime.UtcNow;
            context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(1);
            var refreshToken = context.SerializeTicket();

            token.ProtectedTicket = refreshToken;
            context.SetToken(refreshToken);
            _refreshTokenService.AddRefreshToken(token);
            return(refreshToken);
        }
        private async Task GenerateToken(HttpContext context, string username, Guid audienceId, string clientId)
        {
            var user = _dbContext.Users.Include(x => x.Role).FirstOrDefault(x => x.Email.Equals(username));

            if (user == null)
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Invalid username or password.");

                return;
            }

            var audience = _dbContext.Audiences.FirstOrDefault(x => x.Id == audienceId);

            if (audience == null)
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Invalid audience.");

                return;
            }

            var client = _dbContext.Clients.FirstOrDefault(x => x.Id.Equals(clientId));

            if (client == null)
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Invalid client.");

                return;
            }

            var now = DateTime.UtcNow;

            _options.SigningCredentials = new SigningCredentials(
                new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audience.Base64Secret)),
                SecurityAlgorithms.HmacSha256
                );

            // Specifically add the jti (nonce), iat (issued timestamp), and sub (subject/user) claims.
            // You can add other claims here, if you want:
            var claims = new Claim[]
            {
                new Claim("user_id", user.Id.ToString().ToUpper()),
                new Claim(JwtRegisteredClaimNames.Sub, username),
                new Claim("first_name", user.FirstName),
                new Claim("last_name", user.LastName),
                new Claim("role", user.Role.Name),
                new Claim("organization_id", ""),
                new Claim("avatar", ""),
                new Claim(JwtRegisteredClaimNames.Jti, await _options.NonceGenerator()),
                new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(now).ToString(), ClaimValueTypes.Integer64),
                new Claim("client_id", client.Id)
            };

            // Create the JWT and write it to a string
            var jwt = new JwtSecurityToken(
                issuer: _options.Issuer,
                audience: audience.Id.ToString().ToUpper(),
                claims: claims,
                notBefore: now,
                expires: now.Add(_options.Expiration),
                signingCredentials: _options.SigningCredentials);

            var refreshToken = new RefreshTokens()
            {
                Subject         = user.Email,
                ClientId        = client.Id,
                IssuedUtc       = DateTime.UtcNow,
                ExpiresUtc      = DateTime.UtcNow.AddMinutes(client.RefreshTokenLifetime),
                ProtectedTicket = jwt.ToString()
            };

            refreshToken = await _refreshTokenService.AddRefreshToken(refreshToken);

            await WriteTokenResponse(context, jwt, refreshToken.Id);
        }