на самом деле я новичок в asp.net core 3.1, я пытаюсь создать логин пользователя и зарегистрироваться с помощью файлов cookie.
когда я пытаюсь получить ClaimTypes.NameIdentifier
всегда возвращаю ноль, не могли бы вы мне помочь?
код контроллера
public class AccountController : ControllerBase
{
private readonly ApiSiteDbContext _db;
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
private readonly RoleManager<AppRole> _roleManager;
public AccountController(ApiSiteDbContext db,
UserManager<AppUser> userManager,
SignInManager<AppUser> signInManager,
RoleManager<AppRole> roleManager)
{
_db = db;
_userManager = userManager;
_signInManager = signInManager;
_roleManager = roleManager;
}
[AllowAnonymous]
[HttpPost("Login")]
public async Task<IActionResult> Login(LoginModel loginModel)
{
var user = await _userManager.FindByEmailAsync(loginModel.Email);
// **** this is always return null *****
var id = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (id != null)
{
return BadRequest("User already logged !!");
}
var result = await _signInManager.PasswordSignInAsync(user, loginModel.Password, loginModel.RememberMe, true);
if (result.Succeeded)
{
if (await _roleManager.RoleExistsAsync("User"))
{
if (!await _userManager.IsInRoleAsync(user, "User"))
{
await _userManager.AddToRoleAsync(user, "User");
}
}
var roleName = await GetRoleNameByUserId(user.Id);
if (roleName != null)
{
AddCookies(user.UserName, user.Id, roleName, loginModel.RememberMe, user.Email);
}
return Ok();
}
else if (result.IsLockedOut)
{
return Unauthorized("Your account were locked");
}
return BadRequest("Wrong password!");
//return StatusCode(StatusCodes.Status204NoContent);
}
public async void AddCookies(string userName, string userId, string roleName, bool remember, string email)
{
var claim = new List<Claim>
{
new Claim(ClaimTypes.Name, userName),
new Claim(ClaimTypes.Email, email),
new Claim(ClaimTypes.NameIdentifier, userId),
new Claim(ClaimTypes.Role, roleName),
};
var claimIdentity = new ClaimsIdentity(claim, CookieAuthenticationDefaults.AuthenticationScheme);
if (remember)
{
var authProperties = new AuthenticationProperties
{
AllowRefresh = true,
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddDays(10)
};
await HttpContext.SignInAsync
(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimIdentity),
authProperties
);
}
else
{
var authProperties = new AuthenticationProperties
{
AllowRefresh = true,
IsPersistent = false,
ExpiresUtc = DateTime.UtcNow.AddMinutes(30)
};
await HttpContext.SignInAsync
(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimIdentity),
authProperties
);
}
}
}
и в Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = Context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddControllers();
//services.AddControllersWithViews();
services.AddDbContext<ApiSiteDbContext>();
services.AddIdentity<AppUser, AppRole>(option =>
{
option.Password.RequireDigit = true;
option.Password.RequiredLength = 6;
option.Password.RequiredUniqueChars = 0;
option.Password.RequireLowercase = true;
option.Password.RequireNonAlphanumeric = true;
option.Password.RequireUppercase = true;
option.SignIn.RequireConfirmedEmail = true;
option.Lockout.MaxFailedAccessAttempts = 5;
option.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
}).AddEntityFrameworkStores<ApiSiteDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(options =>
{
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.LogoutPath = "/api/Account/Logout";
//options.LoginPath = "/api/Account/Login";
//options.AccessDeniedPath = "/api/Account/accessDenied";
options.SlidingExpiration = true;
});
services.AddMvc(options => options.EnableEndpointRouting = false)
.SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);
services.AddCors();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(x => x.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod().AllowCredentials());
app.UseMvc();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
когда я делаю эту переменную, чтобы проверить NameIdentifier, если возвращаемый идентификатор или нет, прежде чем использовать его в другом контроллере.
Пожалуйста, предоставьте минимальный, полный и проверяемый пример . Предлагаю прочитать Как задать хороший вопрос и идеальный вопрос
@crgolden это не должно возвращаться каждый раз с нулевым значением, я создаю эту переменную, чтобы гарантировать, что она возвращается со значением, но это не так, она должна быть нулевой при первом входе в систему, и если пользователь зарегистрирован, возвращает неверный запрос с сообщением, которое я проверил.
@MohamedElSoufi при первом входе в систему убедитесь, что вызван метод AddCookies
, иначе у него не будет претензии NameIdentifier
.
Убедитесь, что переменная roleName не является нулевой или пустой строкой, потому что добавление файлов cookie зависит от этого условия.
В вашем методе
Login
, еслиid
!=null
, вы возвращаетеBadRequest
. Это означает, что когда вы в конечном итоге вызываете свой методAddCookies
(где вы добавляете утверждениеNameIdentifier
),id
гарантированно будетnull
в этот момент. Вот почему всегдаnull
, верно?