로그인 만들어보자
★ 로그인은 select지만 post요청을 한다 ★ 원래는 select시 get요청인데.. login만 예외! 외우자!
login은 @PostMapping!!!!! 로그인은 POST!!!!!!!!!
이 코드는 사용자가 입력한 requestDTO(항아리)의 username과 password를 데이터베이스에서 찾아오는 역할 로그인하면 select * from user_tb where username=? and password = ? 라고 쿼리문이 넘어올건데, 이 username과 password의 value 값을 조회하는 코드다 만약 사용자가 입력한 정보와 일치하는 사용자를 찾았다면, 인증이 성공한 것으로 간주하고 (=로그인 성공하고) 해당 사용자 정보를 User 객체로 반환한다. 이름 헷갈려서 적어놓음.. UserRequest = requestDTO = 항아리 = DTO User 객체 = 테이블 만들었던 클래스 = 테이블 형태로 반환 즉, userRepository.findByUsernameAndPassword(requestDTO) 메서드는 JPA를 사용하여 데이터베이스에서 조회한 결과를 자바 객체로 매핑해주는 기능을 제공. 그럼... rs 이런거 없이 파싱한 데이터를 바로 자바 객체에 넣을 수 있겠네?
[ UserRepository 클래스로 가자 ] - DAO
셀렉트는 @Transactional XXX
getSingleResult는 reusultSet이 아니라 object를 리턴하네
User.class = 이 쿼리의 결과를 User 클래스의 객체로 매핑해주세요! Query 객체를 사용하여 데이터베이스에 SQL 쿼리를 생성할 때, 두 번째 매개변수로 결과를 매핑할 클래스를 지정한다. 어떤 클래스의 객체로 변환할지를 알려줘야하기 때문! 그래서 User.class라고 적으면 JPA가 이 쿼리의 결과를 User 클래스의 객체로 변환해주는 것!
그럼 User 객체로 받을거니까 이렇게 쓸 수 있는 듯...? 오브젝트니까 다운캐스팅 해주고요
query.getSingleResult() = 단일 결과를 반환하는 쿼리의 실행 결과를 가져오는 역할
[ UserController 클래스 ]
사용자의 입력 정보인 requestDTO (username, password 인 듯?)를 이용하여 데이터베이스에서 해당 사용자를 찾아오는 코드 즉, DAO 써서 데이터베이스와 상호작용을 하려는 코드 ㅇㅇ
sout(user) 를 찍어서 데이터가 들어오면 아래처럼 보이는 것!
가입하고 '로그인'하니까 콘솔창에 이렇게 나옴 로그인 됐죠? ...된거 맞지?
근데... DS가 뭐지요?
세션 만들자
단순히 페이지만 이동했다고 해서 로그인 상태가 유지되지 않는다. 로그인 상태를 유지하기 위해서는 세션(Session)을 사용하여 사용자의 인증 정보를 저장해야함 그래서 우린 서랍(세션 저장소)를 만들어서 키를 넣을 것이다
지금 현재 로그인해도 쿠키가 없는 것 확인
쿠키가 있으면 이렇게 생겼다...
리퀘스트(Request) 객체를 통해 세션에 접근할 수 있다.
당연함… 클라이언트의 요청 정보는 모두 리퀘스트 객체를 통해 전달되니까…
리퀘스트를 통해 세션에 접근할 수 있는거지 리퀘스트가 세션을 들고 있는게 아니다!!
세션은 서버마다 하나가 있다
메서드의 매개변수로 HttpServletRequest 를 받아야함 (리퀘스트 객체를 통해 접근하니까...) 코드로 세션 영역에 한 번이라도 접근하면 쿠키가 만들어진다. (바로 만들어지는거 X) 근데 이렇게 코드로 안치고 우린 IoC 컨테이너에서 가져올 것이다
로그인 전, 로그인 후 헤더 디자인 변경하기
HttpSession에서 "sessionUser"라는 이름으로 저장된 속성을 가져오는 코드다. HttpSession은 서버 측에서 클라이언트의 상태를 유지하기 위한 저장소다. 이 코드에서는 session 변수가 HttpSession 객체를 참조하고 있으며, getAttribute() 메서드를 사용하여 세션에서 "sessionUser"라는 이름의 속성을 가져온다.
아무튼 이 코드 적어서 로그인 한 후, 메인 페이지에 접근하니까 쿠키가 생겼다. 근데 저 if 거슬리지 않나요? 로그인 후 헤더 디자인을 바꿔보자.
[ 먼저 application-dev 설정하기 ]
mustache: servlet: expose-session-attributes: true expose-request-attributes: true
이렇게 설정해주면 템플릿에서 세션과 요청 속성(Request)에 저장된 데이터를 사용할 수 있다.
[ header.mustache 바꾸기 ]
앞의 설정 덕분에 mastache에서 세션과 관련된 데이터를 사용할 수 있게 됐다. mustache 문법은 # = if ^ = else if 이다. sessionUser (변수명이죠?) 라는 키 값이 있니? 할때 #을 적음
이제 로그인을 하면 로그인, 회원가입 메뉴는 필요 없으니 안 보이게 만들자
로그인 시에는 [글쓰기, 회원정보보기, 로그아웃] 헤더만 보이게 설정 - if(#) 란에 기입
로그인 X 시에는 [회원가입, 로그인] 헤더만 보이게 설정 - else if(^) 란에 기입
로그인 하니까 헤더가 바뀐 것 확인
로그인하니까... 쿠키가 생긴 것도 보이죠? 설명 자세히 해보자...
로그인 오류 잡기 - NoResultException
로그인할 때 'dasflkfjaelfjs' 이런 식으로 DB에 없는 ID로 입력하면 NoResultException으로 터진다
[ NoResultException ? ] 1. 실행한 쿼리에 해당하는 결과가 없을 때 (쿼리 실행 결과로부터 아무런 결과를 받지 못했을 때) 2. 단일 결과를 반환하는 쿼리를 실행하고, 그 결과를 객체로 받을 때
여기서 NoResultException이 터진거다. 받을 때, 결과를 단일 객체로 받을 때 결과 값이 없어서 터져버렸다 (내부적으로 터진 것 → 내가 잡자)
그런데 getSingleResult() 메소드는 내가 만든 것이 아니기 때문에 안의 내용물을 바꿀 수가 없다 내가 직접 try-catch 해주자
이제 정상적으로 error 페이지 나온다!
어디서 터졌는지 printstack을 해도 모르겠으면 이렇게 찾아라!
이렇게 번호를 넣고 터지잖아?
4번까지는 정상 작동됐다는 사실을 알 수 있다. (콘솔창에 5번이 안찍혔으니까 5번이 터졌겠네!)
Share article