이전 게시글
[토이 프로젝트] 회원가입 기능 만들기-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를 사용하는 이유
- 비밀번호와 같은 민감한 데이터를 Body에 담아 전송
- GET은 브라우저나 프록시 서버에 캐싱될 수 있지만, POST는 캐싱되지 않음
- GET을 사용하면 url 뒤로 쿼리스트링이 붙음
- 로그인을 하면 백엔드 쪽에서는 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);
}
그럼 이제 서버 돌려서 테스트!
메인 접속
회원가입 이동
내용 채우고 회원가입 버튼 클릭
성공하면 로그인 화면으로 이동한다.
아이디, 비밀번호 틀리게 입력해보기
올바른 아이디, 비밀번호 입력하기
로그인 성공 시 메인 페이지로 이동한다.
여기까지 로그인 기능 완벽 적용!!
토대를 만들었으니 메인에 로그인 버튼도 만들고....
로그인하면 회원가입도 없애는 등... 작업도 해주고 스프링 시큐리티 도입이나 암호화 적용을 이제 해야겠다.