如何在asp-mvc中使用SignInManager正确登录用户



我尝试创建一个简单的asp-mvc应用程序,在那里我可以注册和登录用户。注册部分似乎在工作,用户被正确地保存在数据库中,但登录功能似乎不起作用。登录后,我无法在放置[Authorize]属性的控制器中进行端点操作。同样在我的导航栏中;寄存器";以及";登录";如果用户登录了,按钮应该会消失,但它们没有。那么我该如何解决这个问题呢?

这是我的代码:

控制器登录方法:

[HttpGet]
public async Task<IActionResult> Login()
{
return View();
}
[HttpPost]
public async Task<IActionResult> LoginPost(LoginViewModel model)
{
if(ModelState.IsValid)
{
//var result = await this._service.SignInWithPassAsync(model.Username,
//    model.Password, model.RememberMe);
var result = await this._signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, false);
if(result.Succeeded)
return RedirectToAction("Index", "Home");
throw new ArgumentException("Login failed!");
}
else
//Invalid Model state. Repeat Login
throw new ArgumentException(
"Problem with Login occurred! Please try again!");
}

服务方式:

public async Task<SignInResult> SignInWithPassAsync(string username,
string password, bool rememberMe)
{
return await this._signInManager
.PasswordSignInAsync(username, password,
rememberMe, false);
}

登录视图模型:

public class LoginViewModel
{
[Required]
[DataType(DataType.Text)]
public string Username { get; set; }

[Required]
[DataType(DataType.Password)]
public string Password { get; set; }

[Display(Name = "Remember Me")]
public bool RememberMe { get; set; }
}

导航栏所在的视图:

@if(User.Identity.IsAuthenticated)
{
<div>Welcome <a asp-action="UserProfile" asp-controller="Account" asp-route-id="@UserManager.GetUserId(User)">@UserManager.GetUserName(User)</a></div>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Login">Login</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Register">Register</a>
</li>
}

经过我的测试,问题可能是由您的startup类引起的。

中间件的顺序应该如下。

app.UseAuthentication();
app.UseAuthorization();

控制器代码:

public class YourController : Controller
{

private readonly ApplicationDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;

public YourController(SignInManager<ApplicationUser> signInManager, UserManager<ApplicationUser> userManager, ApplicationDbContext context)
{           
_context = context;
_userManager = userManager;
_signInManager = signInManager;
}
[Authorize]
public IActionResult Privacy()
{
return View();
}
[HttpGet]
public async Task<IActionResult> Login()
{
return View();
}
[HttpPost]
public async Task<IActionResult> LoginPost(LoginViewModel model)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, false);
if (result.Succeeded)
return RedirectToAction("Index", "Home");
throw new ArgumentException("Login failed!");
}
else
//Invalid Model state. Repeat Login
throw new ArgumentException(
"Problem with Login occurred! Please try again!");
}
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.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
//services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
//    .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentity<IdentityUser, IdentityRole>()
.AddDefaultTokenProviders()
.AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddTransient<IPatientRepository,PatientRepository>();
services.AddTransient<IDoctorRepository, DoctorRepository>();
services.AddTransient<IAppointmentRepository, AppointmentsRepository>();
var context = new CustomAssemblyLoadContext();
context.LoadUnmanagedLibrary(Path.Combine(Directory.GetCurrentDirectory(), "libwkhtmltox.dll"));
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
services.AddControllers();
services.AddElmah<SqlErrorLog>(options => {
options.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
});
services.AddAutoMapper(typeof(Startup));
//services.AddMvc().AddRazorPagesOptions(options => {
//    options.Conventions.AddAreaPageRoute("Identity", "/Account/Login", "");
//}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
//services.AddDbContext<ApplicationDbContext>(options =>
//    options.UseSqlServer(
//        Configuration.GetConnectionString("DbConnectionString")));
//services.AddDefaultIdentity<IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
//    .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.AddMvc().AddRazorPagesOptions(options =>
{
options.Conventions.AddAreaPageRoute("Identity", "/Account/Login", "");
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

//services.Configure<EmailSender>(Configuration.GetSection("Myconfig"));
}
// 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.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();
app.UseElmah();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}

}   

Login Code For SignIn and Roles

if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
var user = await _userManager.FindByNameAsync(Input.Email);
var role = _userManager.GetRolesAsync(user);
string RoleName = string.Empty;
foreach (var Role in role.Result)
{
RoleName = Role;
}
if (RoleName == "Admin")
{
return RedirectToAction(nameof(Appointments.Dashboard), "Appointments");
}
if (RoleName == "Patient")
{
return RedirectToAction(nameof(PatientsController.Index), "Patients");
}
else
{
return RedirectToAction(nameof(DoctorsController.Index), "Doctors");
}
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}

最新更新