Hi, I'm new to this, so I'm not so good, your help is my pleasure.
I have a problem, when I sign up for an account, it is okay, but when I log in, as far as I know, the NormalizeEmail is always null, and I don't know why, I try to cover in the database, but its don't work either. But my UserName ( I set it as email, cause I want people to log in by their email ), is automatically Normalized, I don't know where the problem is. Can someone, help me, please? I would very very appreciate it. If you need to see any file, just comment. Thank you.
This my LoginViewModel
namespace ChatApp_BE.ViewModels
{
public class LoginViewModel
{
public string Email { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
}
Here my User Model
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ChatApp_BE.Models;
public class User : IdentityUser
{
public string? Nickname { get; set; }
public string Email { get; set; } = string.Empty;
public bool EmailConfirmed { get; set; }
public string? PasswordHash { get; set; }
public string? SecurityStamp { get; set; }
public string? FullName { get; set; }
public string? Avatar { get; set; }
public string? EmailConfirmationToken { get; set; }
public string? ResetPasswordToken { get; set; }
public string? RefreshToken { get; set; }
public virtual ICollection<Message> Messages { get; set; } = new List<Message>();
public virtual ICollection<RoomUser> RoomUsers { get; set; } = new List<RoomUser>();
public virtual ICollection<Room> Rooms { get; set; } = new List<Room>();
}
Here is Register
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user != null && await _userManager.IsEmailConfirmedAsync(user))
{
return BadRequest("Email was already used.");
}
user = new User
{
UserName = model.Email,
Email = model.Email,
FullName = model.FullName,
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var confirmationLink = Url.Action(
nameof(ConfirmEmail),
"User",
new { userId = user.Id, token },
Request.Scheme
);
await _emailSender.SendEmailAsync("Confirm your email",
model.Email,
$"Please confirm your email by clicking <a href=\"{confirmationLink}\">here</a>.");
return Ok(new { Message = "Registration successful! Please check your email to confirm your account." });
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return BadRequest(ModelState);
}
Here is Login.
[HttpPost("login")]
public async Task<IActionResult> Login(LoginViewModel model)
{
try
{
if (ModelState.IsValid)
{
var normalizedEmail = _userManager.NormalizeEmail(model.Email);
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null || !await _userManager.CheckPasswordAsync(user, model.Password)) // tu lam sau nhe
{
return Unauthorized("Invalid login attempt.");
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(_config.GetSection("Jwt:SecretKey").Value!);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return Ok(new { Token = tokenString });
}
return BadRequest(ModelState);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}