프로젝트 및 컨퍼런스 회고/프로젝트

[토이 프로젝트] spring boot 로그인 기능 만들기-1

데부한 2025. 2. 27. 16:13
반응형

이전 게시글

 

[토이 프로젝트] 회원가입 기능 만들기-1

사실 아직 만들고 싶은 프로젝트는 생각안해봤다.다만 프로젝트를 해봐야 실력이 정말 늘 것 같아서 일단 대중적이고 레퍼런스 자료가 제일 많은커뮤니티 사이트를 만들어보려한다. 환경은 일

devhan.tistory.com

 

제일 처음으로 회원가입 기능을 만들었다. 회원가입 기능을 고도화할까 하다가 로그인 기능을 먼저 만들고 하는 게 나을 거 같아서 오늘은 로그인 기능을 만들어보겠다.

 

먼저 로그인 화면을 만들어주자. CSS는 일단 회원가입 화면에서 썼던 거 가져왔다.

<body>
<div class="signup-container">
    <form id="loginForm">
        <div>
            <label for="userId">아이디:</label>
            <input type="text" id="userId" name="userId" placeholder="아이디 입력"
                   pattern="^[A-Za-z][A-Za-z0-9]{1,}$"
                   title="영문+숫자. 숫자로 시작하면 안되며 최소 두 글자 이상이어야 합니다." required/>
        </div>
        <div>
            <label for="password">비밀번호:</label>
            <input type="password" id="password" name="password" placeholder="비밀번호 입력" required/>
        </div>
        <div>
            <button type="submit">로그인</button>
        </div>
    </form>
</div>
</body>

그리고 스크립트를 작성해준다.

로그인 기능은 사용자의 정보를 전송하기 때문에 GET으로 요청하기보다는 POST로 요청하는 게 맞다.

<script>
    async function login(event) {
        event.preventDefault();

        const formData = {
              userId : document.getElementById('userId').value
            , password : document.getElementById('password').value
        };

        try {
            const response = await fetch('/api/auth/login', {
                method : 'POST',
                headers : {
                    'Content-Type' : 'application/json'
                },
                body: JSON.stringify(formData)
            });

            if(!response.ok) {
                throw new Error('아이디와 비밀번호를 확인하세요.');
            }

            const data = await response.json();

            alert("로그인 성공");

            window.location.href = "../index.html";
        } catch(error) {
            console.error('Error :', error);
            alert("로그인 실패: " + error.message);
        }
    }

    document.addEventListener('DOMContentLoaded', function() {
        document.getElementById('loginForm').addEventListener('submit', login);
    });

</script>

POST method를 사용하는 이유

  1. 비밀번호와 같은 민감한 데이터를 Body에 담아 전송
  2. GET은 브라우저나 프록시 서버에 캐싱될 수 있지만, POST는 캐싱되지 않음
  3. GET을 사용하면 url 뒤로 쿼리스트링이 붙음
  4. 로그인을 하면 백엔드 쪽에서는 JWT 토큰을 발급하는 등의 상태 변화가 일어남으로 POST가 더 적절

 

이제 백엔드 소스를 만들자.

회원가입 기능 만들때 별 생각없이 패키지를 member로 했는데 auth로 변경하고 파일 이름도 다 변경해줬다.

AuthController에 login()추가

@PostMapping("login")
public ResponseEntity<LoginResponseDto> login(@RequestBody LoginRequestDto loginRequestDto) {
    LoginResponseDto loginResponseDto = authService.login(loginRequestDto);
    return ResponseEntity.ok(loginResponseDto);
}

 

LoginRequestDto, LoginResponseDto 추가

@Getter
public class LoginRequestDto {
    private String userId;
    private String password;
}


// ==============================

@Getter
@AllArgsConstructor
@Builder
public class LoginResponseDto {

    private Long id;
    private String userId;
    private String nickname;
    private String email;
    private String job;
    private int age;

}

 

AuthService에 login() 추가

/**
 * 로그인
 * @param loginRequestDto
 * @return
 */
public LoginResponseDto login(LoginRequestDto loginRequestDto) {
    Member findMember = authRepository.findByUserIdAndPassword(loginRequestDto.getUserId()
            , loginRequestDto.getPassword()).orElseThrow(() -> new IllegalArgumentException("아이디와 비밀번호를 다시 확인하세요."));

    return LoginResponseDto.builder()
            .id(findMember.getId())
            .userId(findMember.getUserId())
            .email(findMember.getEmail())
            .job(findMember.getJob())
            .age(findMember.getAge())
            .nickname(findMember.getNickname())
            .build();
}

 

AuthRepository에 findByUserIdAndPassword() 추가

public interface AuthRepository extends JpaRepository<Member, Long> {
    Optional<Member> findByUserIdAndPassword(String id, String password);
}

 

그럼 이제 서버 돌려서 테스트!

메인 접속

회원가입 이동

내용 채우고 회원가입 버튼 클릭

성공!

성공하면 로그인 화면으로 이동한다.

아이디, 비밀번호 틀리게 입력해보기

실패!

 

올바른 아이디, 비밀번호 입력하기

 

로그인 성공 시 메인 페이지로 이동한다.

 

여기까지 로그인 기능 완벽 적용!!

토대를 만들었으니 메인에 로그인 버튼도 만들고....
로그인하면 회원가입도 없애는 등... 작업도 해주고 스프링 시큐리티 도입이나 암호화 적용을 이제 해야겠다.

반응형