Заменил самописную регистрацию на IdentityCore и поменял миграции

parent 355dfcbe
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Store.Models;
using Store.Models.Users;
using Store.Repositories.Interfaces;
using Store.ViewModels.Auths;
namespace Store.Controllers;
public class AccountsController : Controller
{
private readonly IUserRepository _userRepository;
public AccountsController(IUserRepository userRepository)
private readonly UserManager<User> _userManager;
private readonly SignInManager<User> _signInManager;
public AccountsController(UserManager<User> userManager, SignInManager<User> signInManager)
{
_userRepository = userRepository;
_userManager = userManager;
_signInManager = signInManager;
}
[HttpGet]
......@@ -24,38 +24,38 @@ public class AccountsController : Controller
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model)
{
try
{
if (ModelState.IsValid)
{
var user = _userRepository.GetUserByEmail(model.Email);
if (user is not null)
{
if (user.Password.Equals(model.Password))
{
await AuthenticateAsync(user);
return RedirectToAction("Index", "Home");
}
ModelState.AddModelError("", "пароль введен неверно");
}
else
{
ModelState.AddModelError("", "пользователь не найден");
}
}
return View(model);
}
catch (Exception e)
{
Console.WriteLine(e);
return View();
}
}
// [HttpPost]
// [ValidateAntiForgeryToken]
// public async Task<IActionResult> Login(LoginViewModel model)
// {
// try
// {
// if (ModelState.IsValid)
// {
// var user = _userRepository.GetUserByEmail(model.Email);
// if (user is not null)
// {
// if (user.Password.Equals(model.Password))
// {
// await AuthenticateAsync(user);
// return RedirectToAction("Index", "Home");
// }
// ModelState.AddModelError("", "пароль введен неверно");
// }
// else
// {
// ModelState.AddModelError("", "пользователь не найден");
// }
// }
//
// return View(model);
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// return View();
// }
// }
[HttpGet]
public IActionResult Register()
......@@ -66,58 +66,49 @@ public class AccountsController : Controller
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel viewModel)
{
try
{
if (ModelState.IsValid)
{
var user = _userRepository.GetUserByEmail(viewModel.Email);
if (user is null)
var email = await _userManager.FindByEmailAsync(viewModel.Email);
if (email is null)
{
var role = _userRepository.GetRoles().FirstOrDefault(s => s.Name == "user");
var newUser = new User
var user = new User
{
Email = viewModel.Email,
Password = viewModel.Password,
RoleId = role?.Id,
Role = role
UserName = viewModel.UserName,
BirthDate = viewModel.BirthDate.Date
};
_userRepository.Create(newUser);
_userRepository.Save();
await AuthenticateAsync(newUser);
var result = await _userManager.CreateAsync(user, viewModel.Password);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, true);
return RedirectToAction("Index", "Home");
}
foreach (var error in result.Errors)
ModelState.AddModelError(string.Empty, error.Description);
return View(viewModel);
}
ModelState.AddModelError("", "пользователь с таким email уже существует");
}
return View(viewModel);
}
catch (Exception e)
{
ModelState.AddModelError("", e.Message);
return View(viewModel);
}
}
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction("Login");
}
private async Task AuthenticateAsync(User user)
{
var claims = new List<Claim>
{
new Claim(ClaimsIdentity.DefaultNameClaimType, user.Email),
new Claim(ClaimsIdentity.DefaultNameClaimType, user.Role?.Name)
};
ClaimsIdentity id = new ClaimsIdentity(
claims,
"ApplicationCookie",
ClaimsIdentity.DefaultNameClaimType,
ClaimsIdentity.DefaultRoleClaimType);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(id),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddMinutes(1)
}
);
}
}
\ No newline at end of file
......@@ -20,7 +20,6 @@ public class HomeController : Controller
return View();
}
[Authorize(Roles = "admin, user")]
public IActionResult Privacy()
{
return View();
......
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Store.Models;
using Store.Repositories;
using Store.Repositories.Interfaces;
using Store.Models.Users;
namespace Store.Extensions;
......@@ -11,14 +11,8 @@ public static class ServicesAppExtension
public static void AddAppServices(this IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<AppDbContext>(opt =>
opt.UseNpgsql(configuration.GetConnectionString("ConnectionString")));
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(opt =>
{
opt.LoginPath = new PathString("/Accounts/Login");
});
//repositories
services.AddScoped<IUserRepository, UserRepository>();
opt.UseNpgsql(configuration.GetConnectionString("ConnectionString")))
.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>();
}
}
\ No newline at end of file
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Store.Models;
#nullable disable
namespace Store.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20220718152553_Init")]
partial class Init
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Store.Models.Users.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Roles");
b.HasData(
new
{
Id = 1,
Name = "admin"
},
new
{
Id = 2,
Name = "user"
});
});
modelBuilder.Entity("Store.Models.Users.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("RoleId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("Users");
b.HasData(
new
{
Id = 1,
Email = "email@test",
Password = "1234",
RoleId = 1
});
});
modelBuilder.Entity("Store.Models.Users.User", b =>
{
b.HasOne("Store.Models.Users.Role", "Role")
.WithMany("Users")
.HasForeignKey("RoleId");
b.Navigation("Role");
});
modelBuilder.Entity("Store.Models.Users.Role", b =>
{
b.Navigation("Users");
});
#pragma warning restore 612, 618
}
}
}
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Store.Migrations
{
public partial class Init : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Roles",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Roles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Email = table.Column<string>(type: "text", nullable: false),
Password = table.Column<string>(type: "text", nullable: false),
RoleId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
table.ForeignKey(
name: "FK_Users_Roles_RoleId",
column: x => x.RoleId,
principalTable: "Roles",
principalColumn: "Id");
});
migrationBuilder.InsertData(
table: "Roles",
columns: new[] { "Id", "Name" },
values: new object[,]
{
{ 1, "admin" },
{ 2, "user" }
});
migrationBuilder.InsertData(
table: "Users",
columns: new[] { "Id", "Email", "Password", "RoleId" },
values: new object[] { 1, "email@test", "1234", 1 });
migrationBuilder.CreateIndex(
name: "IX_Users_RoleId",
table: "Users",
column: "RoleId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Roles");
}
}
}
This diff is collapsed.
This diff is collapsed.
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Store.Models.Users;
namespace Store.Models;
public class AppDbContext : DbContext
public class AppDbContext : IdentityDbContext<User>
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> contextOptions) : base(contextOptions)
{
......@@ -15,9 +15,7 @@ public class AppDbContext : DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Role>().HasData(new Role {Id = 1, Name = "admin"});
modelBuilder.Entity<Role>().HasData(new Role {Id = 2, Name = "user"});
modelBuilder.Entity<User>().HasData(new User {Id = 1, Email = "email@test", Password = "1234", RoleId = 1});
base.OnModelCreating(modelBuilder);
}
}
\ No newline at end of file
namespace Store.Models.Users;
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
public List<User> Users { get; set; }
public Role()
{
Users = new List<User>();
}
}
\ No newline at end of file
using Microsoft.AspNetCore.Identity;
namespace Store.Models.Users;
public class User
public class User : IdentityUser
{
public int Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public int? RoleId { get; set; }
public Role? Role { get; set; }
public DateTime BirthDate { get; set; }
}
\ No newline at end of file
using Store.Models;
using Store.Models.Users;
namespace Store.Repositories.Interfaces;
public interface IUserRepository : IRepository<User>
{
User? GetUserById(int id);
User? GetUserByEmail(string email);
List<Role> GetRoles();
}
\ No newline at end of file
using Microsoft.EntityFrameworkCore;
using Store.Models;
using Store.Models.Users;
using Store.Repositories.Interfaces;
namespace Store.Repositories;
public class UserRepository : IUserRepository
{
private readonly AppDbContext _context;
public UserRepository(AppDbContext context)
{
_context = context;
}
public void Create(User item)
{
_context.Users.Add(item);
}
public void Update(User item)
{
_context.Users.Update(item);
}
public void Remove(User item)
{
_context.Users.Remove(item);
}
public void Save()
{
_context.SaveChanges();
}
public User? GetUserById(int id)
{
return _context.Users.Include(u => u.Role).FirstOrDefault(s => s.Id == id);
}
public User? GetUserByEmail(string email)
{
return _context.Users.Include(u => u.Role).FirstOrDefault(s => s.Email == email);
}
public List<Role> GetRoles() => _context.Roles.ToList();
}
\ No newline at end of file
......@@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
......
......@@ -6,6 +6,10 @@ public class RegisterViewModel
{
[Required(ErrorMessage = "Введите email")]
public string Email { get; set; }
[Required(ErrorMessage = "Введите username")]
public string UserName { get; set; }
[Required]
public DateTime BirthDate { get; set; }
[Required(ErrorMessage = "Введите пароль")]
[DataType(DataType.Password)]
public string Password { get; set; }
......
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model Store.ViewModels.Auths.RegisterViewModel
@{
ViewBag.Title = "Регистрация";
}
<h2>Регистрация</h2>
<form asp-action="Register" asp-controller="Accounts" asp-anti-forgery="true">
<div class="validation" asp-validation-summary="ModelOnly"></div>
<div>
<h2>Регистрация нового пользователя</h2>
<form method="post" asp-controller="Accounts" asp-action="Register">
<div asp-validation-summary="ModelOnly"></div>
<div>
<label asp-for="Email">Введите Email</label><br />
<input type="text" asp-for="Email" />
<label asp-for="Email"></label><br/>
<input asp-for="Email"/>
<span asp-validation-for="Email"></span>
</div>
<div>
<label asp-for="Password">Введите пароль</label><br />
<input asp-for="Password" />
<label asp-for="UserName"></label><br/>
<input asp-for="UserName"/>
<span asp-validation-for="UserName"></span>
</div>
<div>
<label asp-for="BirthDate"></label><br/>
<input asp-for="BirthDate" type="date"/>
<span asp-validation-for="BirthDate"></span>
</div>
<div>
<label asp-for="Password"></label><br/>
<input asp-for="Password"/>
<span asp-validation-for="Password"></span>
</div>
<div>
<label asp-for="ConfirmPassword">Повторите пароль</label><br />
<input asp-for="ConfirmPassword" />
<label asp-for="ConfirmPassword"></label><br/>
<input asp-for="ConfirmPassword"/>
<span asp-validation-for="ConfirmPassword"></span>
</div>
<div>
<input type="submit" value="Регистрация" />
</div>
<input type="submit" value="Регистрация"/>
</div>
</form>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment