public async Task <ActionResult> Token(string email, string password) { if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password)) { return(StatusCode((int)HttpStatusCode.BadRequest, Json(new { error = "Email or Password are required" }))); } var account = await _accountCollection.FindAsync(email, "account-email"); if (account == null) { return(StatusCode((int)HttpStatusCode.Unauthorized, Json(new { error = "Invalid credentials" }))); } var hashedPassword = _cryptoService.PasswordCrypt(password, account.PasswordSalt); if (!hashedPassword.Equals(account.Password)) { return(StatusCode((int)HttpStatusCode.Unauthorized, Json(new { error = "Invalid credentials" }))); } var claims = new List <Claim> { new Claim(ClaimTypes.PrimarySid, account._id), new Claim(JwtRegisteredClaimNames.Email, account.Email) }; var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.Keys.JWTSecurityKey)); var jwt = new JwtSecurityToken(new JwtHeader( new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256)), new JwtPayload("kungraseri-api", "kungraseri-audience", claims, null, DateTime.UtcNow.AddDays(1))); var token = new JwtSecurityTokenHandler().WriteToken(jwt); Token savedToken; try { var dbToken = await TokenCollection.FindAsync(account._id, "token-accountid"); savedToken = await TokenCollection.AddOrUpdateAsync( dbToken == null || dbToken.Expiration < DateTime.UtcNow ?new Token { Value = token, AccountId = account._id, Issued = DateTime.UtcNow, Expiration = jwt.ValidTo } : dbToken); } catch (Exception e) { return(StatusCode((int)HttpStatusCode.InternalServerError, Json(new { error = $"Error: {e.Message}. Stack Trace: {e.StackTrace}" }))); } account.Password = string.Empty; account.PasswordSalt = string.Empty; return(StatusCode((int)HttpStatusCode.OK, Json(new { account, token = savedToken }))); }