
- username와 password 정보 가져오기
- findByUsernameAndPassword() 구현하기
- User 테이블은 Entity 타입이라 User.class하면 자동으로 파싱해서 담아줌
package shop.mtcoding.blog.user;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository // IoC에 new하는 방법
public class UserRepository {
// DB에 접근할 수 있는 매니저 객체
// 스프링이 만들어서 IoC에 넣어둔다.
// DI에서 꺼내 쓰기만 하면된다.
private EntityManager em; // 컴포지션
// 생성자 주입 (DI 코드)
public UserRepository(EntityManager em) {
this.em = em;
}
@Transactional // DB에 write 할때는 필수
public void save(UserRequest.JoinDTO requestDTO) { // 컨트롤러는 정보를 전달하면서 때리고 모델에 위임함
// DB에 INSERT할 쿼리문 작성
Query query = em.createNativeQuery("insert into user_tb(username, password, email, created_at) values(?,?,?, now())");
// 가방에 담긴 정보를 DB에 담기
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
query.setParameter(3, requestDTO.getEmail());
query.executeUpdate();
}
public User findByUsernameAndPassword(UserRequest.LoginDTO requestDTO) {
Query query = em.createNativeQuery("select * from user_tb where username=? and password=?", User.class);
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
User user = (User) query.getSingleResult();
return user;
}
}
2. LoginDTO 만들기
package shop.mtcoding.blog.user;
import lombok.Data;
public class UserRequest {
@Data
public static class JoinDTO {
private String username;
private String password;
private String email;
}
@Data
public static class LoginDTO {
private String username;
private String password;
}
}
3. login() 만들기
- @PostMapping을 사용하는 이유
조회문은 원래 get요청이나 민감한 정보는 쿼리 스트링에 담아보낼 수 없음
→ 예외! post 요청하기!
민감한 정보는 BODY 데이터로 보냄
- findByUsernameAndPassword() 호출해서 유효성 검사하기
조회값이 없음 = 인증되지 않음 : error 401
- 조회가 되면 private final HttpSession session; 이 필요함
package shop.mtcoding.blog.user;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@RequiredArgsConstructor
@Controller
public class UserController {
// fianl 변수는 반드시 초기화 되어야 함
private final UserRepository userRepository; // null
private final HttpSession session;
// 원래는 get요청이나 예외 post요청하면 됨
// 민감한 정보는 쿼리 스트링에 담아보낼 수 없음
@PostMapping("/login")
public String login(UserRequest.loginDTO requestDTO) {
System.out.println(requestDTO);
// 1. 유효성 검사
if (requestDTO.getUsername().length() < 3) {
return "error/400";
}
// 2. 모델 필요 select * from user_tb where username=? and password=?
User user = userRepository.findByUsernameAndPassword(requestDTO);
if (user == null) { // 인증 안됨
return "error/401";
} else { // 인증 됨
session.setAttribute("sessionUser", user); // 락카에 담음 (StateFul)
}
return "redirect:/";
}
@PostMapping ("/join")
public String join(UserRequest.joinDTO requestDTO){
System.out.println(requestDTO); //@DATA안에 String도 포함되어있음
// 1. 유효성 검사
if(requestDTO.getUsername().length() <3){
return "error/400";
}
// 2. 동일 username 체크
// 3. Model에게 위임하기
try { // 터트린 것을 잡겠다?
userRepository.save(requestDTO); // 경우의 수가 너무 다양함 : 에러를 명확하게 판단하기 힘듦
} catch(Exception e){
}
return "redirect:/loginForm"; //리다이렉션불러놓은게 있어서 다시부른거
}
@GetMapping("/joinForm") // view만 원함
public String joinForm() {
return "user/joinForm";
}
@GetMapping("/loginForm") // view만 원함
public String loginForm() {
return "user/loginForm";
}
@GetMapping("/user/updateForm")
public String updateForm() {
return "user/updateForm";
}
@GetMapping("/logout")
public String logout() {
return "redirect:/";
}
}
4. 401 에러 페이지 만들기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>인증에 실패하였습니다. 401</h1>
</body>
</html>
5. 로그인 완료

Share article