работает регистрация и вход с шифрованием

This commit is contained in:
EkaterinaR 2024-11-09 23:28:41 +04:00
parent 4f0275f621
commit d61ea1c163
7 changed files with 149 additions and 135 deletions

View File

@ -13,6 +13,8 @@ using System.Xml.Linq;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using static System.Runtime.InteropServices.JavaScript.JSType; using static System.Runtime.InteropServices.JavaScript.JSType;
using DocumentFormat.OpenXml.Office2010.Excel; using DocumentFormat.OpenXml.Office2010.Excel;
using System.Text;
using System.Security.Cryptography;
namespace EventVisitorClientApp.Controllers namespace EventVisitorClientApp.Controllers
{ {
@ -20,7 +22,12 @@ namespace EventVisitorClientApp.Controllers
{ {
Random rnd = new Random(); Random rnd = new Random();
public IActionResult Index() private void DisplayErrorMessage(string message)
{
ViewBag.ErrorMessage = message;
}
public IActionResult Index()
{ {
return View(); return View();
} }
@ -30,8 +37,7 @@ namespace EventVisitorClientApp.Controllers
{ {
return View(); return View();
} }
[HttpPost]
[HttpPost]
public void Enter(string login, string password) public void Enter(string login, string password)
{ {
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password)) if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
@ -114,42 +120,21 @@ namespace EventVisitorClientApp.Controllers
} }
[HttpPost] [HttpPost]
public void Register(string login, string password, string surname, string name, string lastname, string organizationName, string phone, string code) public void Register(string login, string password, string surname, string name, string lastname, string organizationName, string phone)
{ {
if (string.IsNullOrEmpty(login)) APIClient.PostRequest("api/Organizer/Register", new OrganizerBindingModel
{ {
throw new Exception("Ââåäèòå e-mail"); Name = name,
} Surname = surname,
if (string.IsNullOrEmpty(password)) LastName = lastname,
{ OrganizationName = organizationName,
throw new Exception("Ââåäèòå ïàðîëü"); Phone = phone,
} Email = login,
if (string.IsNullOrEmpty(name)) Password = password
{ });
throw new Exception("Ââåäèòå èìÿ"); Response.Redirect("Enter");
} return;
if (string.IsNullOrEmpty(surname)) }
{
throw new Exception("Ââåäèòå ôàìèëèþ");
}
if (string.IsNullOrEmpty(organizationName))
{
throw new Exception("Ââåäèòå íàçâàíèå îðãàíèçàöèè");
}
APIClient.PostRequest("api/Organizer/Register", new OrganizerBindingModel
{
Name = name,
Surname = surname,
LastName = lastname,
OrganizationName = organizationName,
Phone = phone,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
public IActionResult MyEvents() public IActionResult MyEvents()
{ {
@ -206,20 +191,21 @@ namespace EventVisitorClientApp.Controllers
return View(eventDetails); return View(eventDetails);
} }
public IActionResult ResultRegistration()
{
return View();
}
public IActionResult RegistrationOnEvent(int id) public IActionResult RegistrationOnEvent(int id)
{ {
var eventDetails = APIClient.GetRequest<EventViewModel>($"api/main/GetEvent?EventId={id}"); var eventDetails = APIClient.GetRequest<EventViewModel>($"api/main/GetEvent?EventId={id}");
return View(eventDetails); return View(eventDetails);
} }
public IActionResult ResultRegistration()
{
return View();
}
[HttpPost] [HttpPost]
public void RegistrationOnEvent(int id, string name, string phone, string email, DateTime dayBirth) public JsonResult RegistrationOnEvent(int id, string name, string phone, string email, DateTime dayBirth)
{ {
var eventDetails = APIClient.GetRequest<EventViewModel>($"api/main/GetEvent?EventId={id}"); var eventDetails = APIClient.GetRequest<EventViewModel>($"api/main/GetEvent?EventId={id}");
@ -263,11 +249,11 @@ namespace EventVisitorClientApp.Controllers
Subject = "Ðåãèñòðàöèÿ íà ìåðîïðèÿòèå", Subject = "Ðåãèñòðàöèÿ íà ìåðîïðèÿòèå",
Text = "Âû çàðåãåñòðèðîâàíû íà ìåðîïðèÿòèå " + eventDetails.Name + ", êîòîðîå ïðîéäåò " + eventDetails.TimeStart + ". Ïî àäðåñó: " + eventDetails.Address + " ã. " + eventDetails.City + ".\n" + "Ïî âñåì âîïðîñàì ìîæíî îáðàùàòüñÿ ïî òåëåôîíó: " + eventDetails.ContactPhone + " èëè ïî ïî÷òå: " + eventDetails.ContactEmail + ".\n" + "Áóäåì æäàòü Âàñ íà íàøèõ ìåðîïðèÿòèÿõ!" Text = "Âû çàðåãåñòðèðîâàíû íà ìåðîïðèÿòèå " + eventDetails.Name + ", êîòîðîå ïðîéäåò " + eventDetails.TimeStart + ". Ïî àäðåñó: " + eventDetails.Address + " ã. " + eventDetails.City + ".\n" + "Ïî âñåì âîïðîñàì ìîæíî îáðàùàòüñÿ ïî òåëåôîíó: " + eventDetails.ContactPhone + " èëè ïî ïî÷òå: " + eventDetails.ContactEmail + ".\n" + "Áóäåì æäàòü Âàñ íà íàøèõ ìåðîïðèÿòèÿõ!"
}); });
Response.Redirect("ResultRegistration"); return Json(new { success = true });
} }
else else
{ {
Response.Redirect("NoFreePlaces"); return Json(new { success = false });
} }
} }

View File

@ -5,7 +5,7 @@
<div class="containerenter text-center mt-5"> <div class="containerenter text-center mt-5">
<h2 class="display-4 mb-4">Регистрация</h2> <h2 class="display-4 mb-4">Регистрация</h2>
<form method="post" class="border p-4 rounded"> <form method="post" id="registrationForm" class="border p-4 rounded">
<div class="mb-4"> <div class="mb-4">
<label for="InputEmail1" class="form-label" style="font-size: 24px";>Введите e-mail</label> <label for="InputEmail1" class="form-label" style="font-size: 24px";>Введите e-mail</label>
<input type="email" name="login" class="form-control" id="InputEmail1" required> <input type="email" name="login" class="form-control" id="InputEmail1" required>
@ -61,62 +61,4 @@
} }
</style> </style>
<div class="modal fade" id="confirmationModal" tabindex="-1" aria-labelledby="confirmationModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmationModalLabel">Введите код подтверждения</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<label for="confirmationCode" class="form-label">Код подтверждения</label>
<input type="text" name="confirmationCode" class="form-control" id="confirmationCode">
<input type="hidden" name="code" id="confirmationCodeHidden" value="">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" id="confirmCodeButton" class="btn btn-primary">Подтвердить</button>
</div>
</div>
</div>
</div>
<script>
// Показ модального окна при успешной отправке формы
document.forms[0].onsubmit = function (e) {
e.preventDefault(); // Остановить стандартное поведение
$('#confirmationModal').modal('show');
};
document.getElementById('confirmCodeButton').onclick = function () {
const confirmationCode = document.getElementById('confirmationCode').value;
if (confirmationCode) {
// Устанавливаем значение кода в скрытое поле
document.getElementById('confirmationCodeHidden').value = confirmationCode;
// Закрываем модальное окно
$('#confirmationModal').modal('hide');
// Отправляем форму
document.forms[0].submit(); // Отправляет первую форму на странице
} else {
alert("Введите код подтверждения.");
}
};
// Валидация формы
(function () {
'use strict'
const forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>

View File

@ -47,7 +47,7 @@
<div class="containerenter text-center"> <div class="containerenter text-center">
<h2 class="display-4 mb-4">Регистрация на мероприятие</h2> <h2 class="display-4 mb-4">Регистрация на мероприятие</h2>
<form method="post" class="border p-4 rounded"> <form method="post" id="registrationForm" class="border p-4 rounded">
<div class="mb-4"> <div class="mb-4">
<label for="InputName" class="form-label" style="font-size: 24px;">Введите имя</label> <label for="InputName" class="form-label" style="font-size: 24px;">Введите имя</label>
<input type="text" name="name" class="form-control" id="name" required> <input type="text" name="name" class="form-control" id="name" required>
@ -80,6 +80,22 @@
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" id="registrationSuccessModal" tabindex="-1" aria-labelledby="registrationSuccessModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="registrationSuccessModalLabel">Успешно зарегистрировано!</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
Вы зарегистрировались успешно! Проверьте почту. Мы прислали вам сообщение с информацией о мероприятии.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
</div>
</div>
</div>
</div>
</html> </html>
@ -92,3 +108,27 @@
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
} }
</style> </style>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$('#registrationForm').on('submit', function (e) {
e.preventDefault(); // Предотвращаем стандартное поведение формы
$.ajax({
type: "POST",
url: '@Url.Action("RegistrationOnEvent", "Home")',
data: $(this).serialize(), // Сериализуем данные формы
success: function (response) {
// Если регистрация успешна
if (response.success) {
$('#registrationSuccessModal').modal('show'); // Показываем модальное окно
} else {
alert("Нет свободных мест!"); // Или обработка ошибки
}
},
error: function () {
alert("Произошла ошибка при регистрации.");
}
});
});
</script>

View File

@ -1,25 +1,25 @@
@model ErrorViewModel <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<h2 class="text-danger">An error occurred while processing your request.</h2> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
@if (Model.ShowRequestId) <div id="errorModal" class="modal" tabindex="-1" role="dialog">
{ <div class="modal-dialog" role="document">
<p> <div class="modal-content">
<strong>Request ID:</strong> <code>@Model.RequestId</code> <div class="modal-header">
</p> <h5 class="modal-title">Ошибка</h5>
} <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
<h3>Development Mode</h3> </button>
<p> </div>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred. <div class="modal-body">
</p> <p>@ViewBag.ErrorMessage</p>
<p> </div>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong> <div class="modal-footer">
It can result in displaying sensitive information from exceptions to end users. <button type="button" class="btn btn-secondary" data-dismiss="modal">Закрыть</button>
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong> </div>
</div>
</div>
</div>
and restarting the app. and restarting the app.
</p> </p>

View File

@ -33,8 +33,9 @@ namespace EventVisitorDatabase.Implements
return null; return null;
} }
using var context = new EventVisitorDbContext(); using var context = new EventVisitorDbContext();
if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password)) if (!string.IsNullOrEmpty(model.Email))
return context.Organizers.FirstOrDefault(x => x.Email.Equals(model.Email) && x.Password.Equals(model.Password))?.GetViewModel; return context.Organizers.FirstOrDefault(x => x.Email.Equals(model.Email))?.GetViewModel;
return context.Organizers. return context.Organizers.
FirstOrDefault(x => (x.Id == model.Id))? FirstOrDefault(x => (x.Id == model.Id))?

View File

@ -4,7 +4,9 @@ using EventVisitorLogic.ViewModels;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace EventVisitorLogic.Logic namespace EventVisitorLogic.Logic
@ -16,9 +18,17 @@ namespace EventVisitorLogic.Logic
{ {
_organizerStorage = organizerStorage; _organizerStorage = organizerStorage;
} }
private string EncryptPassword(string password)
{
byte[] hashedBytes = SHA256.HashData(Encoding.UTF8.GetBytes(password));
return Convert.ToBase64String(hashedBytes);
}
public bool Create(OrganizerBindingModel model) public bool Create(OrganizerBindingModel model)
{ {
CheckModel(model); CheckModel(model);
model.Password = EncryptPassword(model.Password);
var result = _organizerStorage.Insert(model); var result = _organizerStorage.Insert(model);
if (result == null) if (result == null)
@ -44,12 +54,28 @@ namespace EventVisitorLogic.Logic
{ {
throw new ArgumentNullException(nameof(model)); throw new ArgumentNullException(nameof(model));
} }
var element = _organizerStorage.GetElement(model); var element = _organizerStorage.GetElement(model);
if (element == null) if (element != null)
{ {
return null; string hashedPassword = element.Password;
if (element != null && model.Password != element.Password && model.Password != null)
{
hashedPassword = EncryptPassword(model.Password);
}
if (element == null)
{
return null;
}
else
{
if (element.Password == hashedPassword)
{
return element;
}
}
} }
return element; return null;
} }
public List<OrganizerViewModel>? ReadList(OrganizerBindingModel? model) public List<OrganizerViewModel>? ReadList(OrganizerBindingModel? model)
@ -107,6 +133,25 @@ namespace EventVisitorLogic.Logic
{ {
throw new ArgumentNullException("Нет пароля", nameof(model.Password)); throw new ArgumentNullException("Нет пароля", nameof(model.Password));
} }
if (!Regex.IsMatch(model.Email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase))
{
throw new ArgumentException("Неправильно введенный email", nameof(model.Email));
}
if (!Regex.IsMatch(model.Password, @"^^((\w+\d+\W+)|(\w+\W+\d+)|(\d+\w+\W+)|(\d+\W+\w+)|(\W+\w+\d+)|(\W+\d+\w+))[\w\d\W]*$", RegexOptions.IgnoreCase))
{
throw new ArgumentException("Неправильно введенный пароль", nameof(model.Password));
}
var element = _organizerStorage.GetElement(new OrganizerBindingModel
{
Email = model.Email
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Пользователь с такой почтой уже есть");
}
} }
} }
} }

View File

@ -45,7 +45,7 @@ namespace EventVisitorRestApi.Controllers
} }
catch (Exception ex) catch (Exception ex)
{ {
throw; BadRequest(new { message = ex.Message });
} }
} }
[HttpPost] [HttpPost]