LoginController.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using Microsoft.AspNetCore.Mvc;
  2. using bitforum.Models.Log;
  3. using bitforum.DTOs.Request;
  4. using bitforum.DTOs.Response;
  5. using bitforum.Helpers;
  6. using bitforum.Services;
  7. using bitforum.Repository;
  8. namespace bitforum.Controllers.API.Auth
  9. {
  10. [ApiController]
  11. [Route("api/auth")]
  12. public class LoginController : ControllerBase
  13. {
  14. private readonly ILogger<LoginController> _logger;
  15. private readonly DefaultDbContext _db;
  16. private readonly IJwtAuthService _jwtAuthService;
  17. private readonly IMemberRepository _memberRepository;
  18. private ResultDto _result = new ResultDto();
  19. public LoginController(ILogger<LoginController> logger, DefaultDbContext db, IJwtAuthService jwtAuthService, IMemberRepository memberRepository)
  20. {
  21. _logger = logger;
  22. _db = db;
  23. _jwtAuthService = jwtAuthService;
  24. _memberRepository = memberRepository;
  25. }
  26. // 로그인
  27. [HttpPost("login")]
  28. public async Task<ActionResult<ResultDto>> Login([FromBody] LoginDto request)
  29. {
  30. var loginLog = new LoginLog();
  31. try
  32. {
  33. // 유효성 검사
  34. if (!ModelState.IsValid)
  35. {
  36. _result.Errors = ModelState.GetErrors();
  37. throw new Exception("유효성 검사에 실패하였습니다.");
  38. }
  39. loginLog.Account = request.Email;
  40. loginLog.Referer = HttpContext.Request.Headers["Referer"].ToString();
  41. loginLog.Url = HttpContext.Request.Path.ToString();
  42. loginLog.IpAddress = HttpContext.GetClientIP();
  43. loginLog.UserAgent = Request.Headers["User-Agent"].ToString();
  44. // 계정 확인
  45. var member = await _memberRepository.FindMemberByEmail(request.Email);
  46. if (member == null)
  47. {
  48. loginLog.Reason = "계정을 찾을 수 없음";
  49. throw new Exception("해당 정보로 귀하의 계정을 확인할 수 없습니다.");
  50. }
  51. if (member.IsDenied)
  52. {
  53. loginLog.Reason = "접속 차단되었음";
  54. throw new Exception("접속이 차단되어 로그인이 불가합니다.");
  55. }
  56. if (!BCrypt.Net.BCrypt.Verify(request.Password, member.Password))
  57. {
  58. loginLog.Reason = "비밀번호 틀림";
  59. throw new Exception("해당 정보로 귀하의 계정을 확인할 수 없습니다.");
  60. }
  61. // 로그인 기록
  62. loginLog.MemberID = member.ID;
  63. loginLog.Success = true;
  64. loginLog.Reason = "로그인 성공";
  65. loginLog.CreatedAt = DateTime.UtcNow;
  66. // 로그인 시간, IP 갱신
  67. member.LastLoginIp = HttpContext.GetClientIP();
  68. member.LastLoginAt = DateTime.UtcNow;
  69. // JWT 토큰 발급
  70. _jwtAuthService.SetAccessTokenAndCookieAsync(member);
  71. await _jwtAuthService.SetRefreshTokenAndCookieAsync(member);
  72. _result.Message = "로그인 성공";
  73. }
  74. catch (Exception e)
  75. {
  76. _logger.LogError(e, e.Message);
  77. _result.Ok = false;
  78. _result.Status = StatusCodes.Status400BadRequest;
  79. _result.Message = e.Message;
  80. }
  81. await _db.LoginLog.AddAsync(loginLog);
  82. await _db.SaveChangesAsync();
  83. return _result;
  84. }
  85. }
  86. }