/
ibavca1
/
A4.ControlPost
Обзор
Документация
Войти
/
ibavca1
/
A4.ControlPost
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/A4.ControlPost.Server/Controllers/AuthController.cs
220 строк
8 KB
ibavca
Востановление пароля
17 май 2026, 08:55
17 май 2026, 08:55
d834def
Код
Авторство
О чём код?
// src/A4.ControlPost.Server/Controllers/AuthController.cs using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using A4.ControlPost.Core.Models; using A4.ControlPost.Server.Data; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.WebUtilities; using Microsoft.IdentityModel.Tokens; namespace A4.ControlPost.Server.Controllers; [ApiController] [Route("api/[controller]")] public class AuthController : ControllerBase { private readonly UserManager<ApplicationUser> _userManager; private readonly SignInManager<ApplicationUser> _signInManager; private readonly IConfiguration _config; public AuthController( UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, IConfiguration config) { _userManager = userManager; _signInManager = signInManager; _config = config; } /// <summary> /// Регистрация нового пользователя /// </summary> [HttpPost("register")] public async Task<IActionResult> Register([FromBody] UserRegister model) { if (!ModelState.IsValid) return BadRequest(ModelState); var existingUser = await _userManager.FindByNameAsync(model.UserName); if (existingUser != null) return BadRequest(new { Message = "Имя пользователя занято" }); var existingEmail = await _userManager.FindByEmailAsync(model.Email); if (existingEmail != null) return BadRequest(new { Message = "Email уже используется" }); var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, CreatedAt = DateTime.UtcNow }; var result = await _userManager.CreateAsync(user, model.Password); if (!result.Succeeded) return BadRequest(result.Errors); // Назначаем роль по умолчанию await _userManager.AddToRoleAsync(user, "user"); return Ok(new { Message = "Пользователь зарегистрирован", UserId = user.Id }); } /// <summary> /// Вход и получение JWT /// </summary> [HttpPost("login")] public async Task<IActionResult> Login([FromBody] UserLogin model) { if (!ModelState.IsValid) return BadRequest(ModelState); var user = await _userManager.FindByNameAsync(model.UserName); if (user == null) return Unauthorized(new { Message = "Неверный логин или пароль" }); var result = await _signInManager.CheckPasswordSignInAsync(user, model.Password, lockoutOnFailure: false); if (!result.Succeeded) return Unauthorized(new { Message = "Неверный логин или пароль" }); var token = GenerateJwtToken(user); return Ok(new { Token = token }); } private string GenerateJwtToken(ApplicationUser user) { var roles = _userManager.GetRolesAsync(user).Result; if(user ==null) return ""; var claims = new List<Claim> { new Claim(JwtRegisteredClaimNames.Sub, user.UserName!), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(ClaimTypes.Name, user.UserName!), new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Email, user.Email ?? "") }; foreach (var role in roles) { claims.Add(new Claim(ClaimTypes.Role, role)); } var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JwtSettings:Secret"]!)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: _config["JwtSettings:Issuer"], audience: _config["JwtSettings:Audience"], claims: claims, expires: DateTime.Now.AddMinutes(60), signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); } /// <summary> /// Запрос на подтверждение email (например, при регистрации) /// </summary> [HttpPost("send-email-confirmation")] [Authorize] public async Task<IActionResult> SendEmailConfirmation() { var user = await _userManager.GetUserAsync(User); if (user == null) return NotFound(); if (user.EmailConfirmed) return BadRequest(new { Message = "Email уже подтверждён" }); var token = await _userManager.GenerateEmailConfirmationTokenAsync(user); var encodedToken = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token)); // В реальности — отправь письмо с ссылкой: // https://yoursite.com/confirm-email?userId=...&token=... // Здесь просто возвращаем для теста return Ok(new { Message = "Токен подтверждения email сгенерирован", UserId = user.Id, Token = encodedToken // Только для тестов! В продакшене — не возвращать! }); } /// <summary> /// Подтвердить email по токену /// </summary> [HttpGet("confirm-email")] public async Task<IActionResult> ConfirmEmail(string userId, string token) { if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(token)) return BadRequest("Необходимы userId и token"); var user = await _userManager.FindByIdAsync(userId); if (user == null) return NotFound(); var decodedToken = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(token)); var result = await _userManager.ConfirmEmailAsync(user, decodedToken); if (!result.Succeeded) return BadRequest(result.Errors); return Ok(new { Message = "Email успешно подтверждён!" }); } /// <summary> /// Запрос на сброс пароля (по email) /// </summary> [HttpPost("forgot-password")] public async Task<IActionResult> ForgotPassword([FromBody] ForgotPassword model) { if (!ModelState.IsValid) return BadRequest(ModelState); var user = await _userManager.FindByEmailAsync(model.Email); if (user == null) return Ok(new { Message = "Если email существует — ссылка отправлена" }); // Безопасность: не раскрываем существование аккаунта var token = await _userManager.GeneratePasswordResetTokenAsync(user); var encodedToken = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token)); // В реальности: отправь письмо с: // https://yoursite.com/reset-password?userId={user.Id}&token={encodedToken} // Для теста — просто вернём токен return Ok(new { Message = "Ссылка для сброса пароля сгенерирована", UserId = user.Id, Token = encodedToken }); } /// <summary> /// Сброс пароля по токену /// </summary> [HttpPost("reset-password")] public async Task<IActionResult> ResetPassword([FromBody] ResetPassword model) { if (!ModelState.IsValid) return BadRequest(ModelState); var user = await _userManager.FindByIdAsync(model.UserId); if (user == null) return NotFound(); var decodedToken = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(model.Token)); var result = await _userManager.ResetPasswordAsync(user, decodedToken, model.NewPassword); if (!result.Succeeded) return BadRequest(result.Errors); return Ok(new { Message = "Пароль успешно изменён" }); } }