🔹프론트에서 정보를 넘겨줄 수 있는 구조가 되어있는지 먼저 확인해야된다.
🔹method 자리에 공백이 되면 기본 디폴트 값은 get
🔹enctype 자리에 공백이 되면 기본 디폴트 값은 xform데이터
🔹 name 속성 있는지 확인하고 받을 값의 이름이 일치하는지 확인
🔷 @ Form 태그와 Input태그 개념
2️⃣ 클라이언트 정보 받기 - DTO안 쓸때
🔷 방법 1
💡
⭐ 왜 post를 사용하나??
➖get요청으로 정보를 전달하면, 이는 URL로 노출이 되게된다.
➖ 그래서 민감한 정보는 바디데이터로 보내야된다. 그래서 post요청
🔹 매개변수에 파라메터로 사용해서 정보를 받을 수 있다. 하지만 위험!!
🔷 방법 2
💡
🔹 그림 다시 그려서 정리하자
🔹 톰캣의 HttpServletRequest 클래스를 사용하여서 정보를 받아온다.
🔹 request.getParameter 에 키값을 사용해서 가져온다.
3️⃣ DTO 만들기 - 우린 DTO 사용한다.
💡
⭐ DTO(Data Transfer Object, 데이터 전송 객체)란 프로세스 간에 데이터를 전달하는 객체를 의미합니다.
🔹 사용자를 입력한 정보를 객체에 담아서 사용한다.
🔹 클라이언트가 서버측으로 전송하는 데이터
🔹 DB에서 Entity로 받고, Entity에서 DTO로 필요한 정보를 추려내서 브라우저에 전달
Java
package shop.mtcoding.blog.user;
import lombok.Data;
public class UserRequest {
@Data // Getter, Setter, toString 자동 생성
public class LoginDTO { //login정보로 사용할 DTO객
private String username;
private String password;
}
}
🔷 값 받기 테스트
💡
🔹 login액션이 들어오면 해당 메소드 실행
🔹 return에서 리다이렉트를 않고 연결하면 로그인 정보를 얻자마자 버리는 셈
🔹 로그인 정보를 가지고 이동할려면 반드시 redirect: 사용!!!
🔹 로그인을 위해서는 session.setAttribute가 필요하기 떄문에 의존성 주입!!
Java
@RequiredArgsConstructor //의존성 주입용 생성자생성
@Controller // IoC 컨테이너에 등록
public class UserController {
private final UserRepository userRepository;
private final HttpSession session; // 세션을 DI해서 로그인 사용자 세션 부여시 사용
@PostMapping ("/login") // html에서 'login'액션이 들어오면 해당 메소드 실행
public String login (UserRequest.LoginDTO requestDTO){
System.out.println(requestDTO); // 값이 잘 넘어오는지 테스
return "redirect:/"; // 여기서 리다이렉트를 하지 않으면
} // 로그인 정보를 버리고 새로 요청하게됨
} // 정보를 가지고 이동할려면 리다이렉트로 메인페이지 연결
4️⃣ 컨트롤러에 책임 부여하기
🔹 login메소드 전체 코드
Java
@PostMapping("/login")
public String login(UserRequest.LoginDTO requestDTO){
// 1번 유효성 검사 - 아이디 길이가 3자 이하일 때
if(requestDTO.getUsername().length() < 3){
return "error/400"; // ViewResolver 설정이 되어 있음. (앞 경로, 뒤 경로 자동설정)
}
User user = userRepository.findByUsernameAndPassword(requestDTO);
// 2번 유효성 검사 - 아이디 비밀번호가 틀려서 조회가 안될 때
if(user == null){
// 조회 안됨 (401)
return "error/401";
}else{
// 조회 됐음 (인증됨)
// HttpSession을 의존성 주입을 받아서 사용 - 락카에 담음 (StateFul)
// HttpSession이란 해쉬맵에 키값 'sessionUser'에 밸류값을 'user'
session.setAttribute("sessionUser", user);
}
return "redirect:/"; // 컨트롤러가 존재하면 무조건 redirect 외우기
}
💡
⭐ 의존성 주입
🔹 @RequriedArgConstructor 사용하여 final선언된 HttpSession을 가져다 쓸 수 있다.
🔷 1번 유효성 검사 - 아이디 길이가 3자 이하일 때
💡
🔹 400번 에러페이지 만들기 → 프론트 작업 또는 View만들기
🔹 400번 응답코드는 클라이언트 쪽의 잘못된 요청
🔹 유효성을 통과하였다면 아래 코드를 만들어서 UserController >> login 메소드 내부에 구현한다.
🔹 메소드가 길더라도 메소드 자체에서 의미를 바로 파악할 수 있게끔 만드는 것이 포인트!!
🔹 아마 빨간색일텐데, 이는 아직 해당메소드 로직을 구현하지 않았기 때문
🔹 alt+enter으로 들어가면 자동으로 필요한 매개변수와 함께 만들어준다.
Java
// login메소드 내부에 유효성 검사 통과 후 구현
userRepository.findByUsernameAndPassword(requestDTO);
💡
결과 - 자동으로 틀을 만들어 준다. 이 내부에 로직을 구현한다.
🔷 쿼리 작성
💡
🔹 자바에 쿼리를 먼저 실행해보기 전에 데이터베이스에서 쿼리가 실제 작동하는지 쿼리문 테스트를 먼저 실행한다.
Java
// 테스트 쿼리문
// 먼저 데이터를 넣고 조회가 되는지 테스트
// 문자열에 쌍따옴표가 아니라 홑따옴표 기억하자
select * from user_tb where username='ssar' and password='1234'
💡
🔹 테스트 확인. DB에서 직접 테스트 할려면 문자열은 ''로 감싸야된다.
🔹 H2 콘솔로 로그인하여서, insert into 후에 테스트를 해봐야된다.
🔷 메소드 구현
💡
⭐ ORM은 데이터베이스 테이블을 객체 (클래스)로 변환해주는 역할, JPA (Java Persistence API)와 같은 ORM 프레임워크를 사용하여 데이터베이스 테이블을 Java 클래스로 매핑
🔹 두개의 값을 받으므로 객체로 담아야 된다. User 클래스 사용
🔹 em변수로 EntityManager를 사용중이므로, 결과값을 받아서 바로 User클래스에 매핑해 주는 문법이 User.class 사용이다.
🔹 User.class 를 적을 수 있는 이유는 User 엔티티가 구현되어 있어야 한다.
이렇게 되면 자동으로 User클래스에 Table 데이터를 파싱해서 담아준다.
Java
public void findByUsernameAndPassword(UserRequest.LoginDTO requestDTO) {
//em변수로 EnityManager를 사용중이므로, 결과값을 받아서 바로 User클래스에 매핑해 주는 문법이 User.class 사용이다.
Query query = em.createNativeQuery("select * from user_tb where username=? and password=?", User.class);
// ?를 변수화 하여서 setParmeter로 값을 지정한다. '1'이 첫 번째 매개변수라면 1번째 물음표에 대입하라라는 뜻
query.setParameter(1, requestDTO.getUsername());
query.setParameter(2, requestDTO.getPassword());
// 하나의 결과값만 기대하기 때문에 getSinglerResult 사용
User user = (User) query.getSingleResult();
return user;
}
💡
이렇게 User클래스에 @Enitity 선언이 되어있어야지 EntityManager를 통해 User.class를 사용 할 수 있다.
5️⃣ 로그인 테스트 확인
💡
🔹 잘 작동하는지 확인
🔹 로그인 성공후 서버로 부터 set-cookie값을 받았다
💡
개발자도구>> Application>> Cookies로 들어가보면 jsessionid를 확인할 수 있다.