728x90
대망의 spring 로그인 기능 구현하기 3번째 내용입니다.
이번 시간으로 해서 로그인 기능에 관한 것은 마치겠습니다!!
1. Session : 세션을 직접 만든다?! NO NO!!
사실 이전 세션을 활용한 로그인 구현의 내용은 정말로 내가 직접 세션으로서 동작할 수 있도록 기능을 '만들어서' 로그인 할 수 있도록 했다. 그런데 사실 모든 사이트에서 매번 이렇게 세션을 직접 만들어서 사용하는 것은 굉장히...골아프고 힘든 일이다. 이에 HTTP 서블릿 에서 HttpSession 을 제공한다. 이번에는 이를 활용해서 로그인 하는 기능을 만들어보겠다.
1) HttpSession
HTTP서블릿에서 지원하는 HttpSession 은 다음과 같은 특징을 갖는다.
- 이전에 만들었던 SessionManager 와 같은 방식으로 동작한다. 즉, 우리가 따로 만들어줄 필요가 없다.
- 서블릿을 통해 HttpSession 을 생성하면 다음과 같은 쿠키를 생성한다.
- 쿠키 이름은 JSESSIONID, 값은 역시 추정불가능한 UUID 값
2) 코드로 구현하기
request.getSession(true, false) 차이
- request.getSession(true)
- 세션이 있으면 기존 세션 반환
- 세션이 없으면 새로운 세션 생성해서 반환
- request.getSession(false)
- 세션이 있으면 기존 세션 반환
- 세션이 없으면 새로운 세션 생성 X => null 반환
- 홈페이지에 처음 들어온 사람이며 로그인 안한 사람의 경우 세션을 만들 필요가 없고 이때 false 가 사용됨
2. JSesssionID 사용하기
http 서블릿에서 지원하는 session 기능을 사용하기 위해 새로운 homeController 와 LoginController 을 만들어줍니다.
- new_homeController
package HJproject.Hellospring.Controller;
import HJproject.Hellospring.Session.SessionConst;
import HJproject.Hellospring.Session.SessionManager;
import HJproject.Hellospring.domain.member.Member;
import HJproject.Hellospring.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Optional;
@Controller
@RequiredArgsConstructor
public class new_HomeController {
private final MemberRepository memberRepository;
// @GetMapping("/") // 직접 만든 세션을 사용한 로그인
public String LoginHomeWithHttpSession(HttpServletRequest request, Model model) {
// 로그인 안했을 시
HttpSession session = request.getSession(false);
if(session == null){
return "newspringhome";
}
/* 로그인 시도 시 */
Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
if(loginMember.getCode() == null){
// 각각 로그인을 시도했으나 회원 코드가 없는 경우, 회원코드가 0 인 경우, 회원 코드가 0 이 아닌 경우
return "newspringhome";
}else if(loginMember.getCode() == 0){
session.getAttribute(session.getId());
model.addAttribute("member", loginMember);
System.out.println("관리자 로그인 성공");
/** 이런식으로 session에 담아져있는 값을 가져올 수 있음 */
System.out.println(session.getAttribute("memberCode"));
/** 이런식으로 세션 토큰 값을 가져올 수 있음 **/
System.out.println("JSESSIONID :"+request.getRequestedSessionId());
return "newspringhome_admin";
}else {
model.addAttribute("member", loginMember);
System.out.println("일반 회원 로그인 성공");
System.out.println("JSESSIONID :"+request.getRequestedSessionId());
return "newspringhome_login";
}
}
@GetMapping("/") // 스프링이 지원하는 세션 기능 : @SessionAttribute
public String LoginHomeWithHttpSessionv2(
// 기능은 이전과 동일. 즉 SessionConst.LOGIN_MEMBER 참고하여 세션 유무 확인 후 없으면 null 반환
// 로그인 하면 member 에 담은 것 활용해서 로그인 세션 기능 제공
@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model) {
// 로그인 안했을 시
// 스프링이 알아서 처리해줌 만세!
/* 로그인 시도 시 */
// 각각 로그인을 시도했으나 회원 코드가 없는 경우, 회원코드가 0 인 경우, 회원 코드가 0 이 아닌 경우
if(loginMember == null){
return "newspringhome";
}else if(loginMember.getCode() == 0){
model.addAttribute("member", loginMember);
System.out.println("관리자 로그인 성공");
return "newspringhome_admin";
}else {
model.addAttribute("member", loginMember);
System.out.println("일반 회원 로그인 성공");
return "newspringhome_login";
}
}
}
- new_LoginController
package HJproject.Hellospring.Controller;
import HJproject.Hellospring.Session.SessionConst;
import HJproject.Hellospring.Session.SessionManager;
import HJproject.Hellospring.domain.login.LoginForm;
import HJproject.Hellospring.domain.member.Member;
import HJproject.Hellospring.service.LoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Slf4j
@Controller
@RequiredArgsConstructor // 클래스의 final 필드에 대한 생성자를 자동으로 생성
public class new_LoginController {
private final LoginService loginService;
private final SessionManager sessionManager; // @Component 필요
@GetMapping("/login")
public String LoginForm(@ModelAttribute("LoginForm")LoginForm form){
return "members/login";
}
@PostMapping("/login") // http 서블릿 세션 활용 로그인
public String loginWithHttpSession(@ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletRequest request) {
if (bindingResult.hasErrors()) {
return "members/login";
}
// 1. loginForm 을 통해 값들을 가져옴
Member LoginMember = loginService.login(form.getLoginid(), form.getLoginpw());
if (LoginMember == null) { // login 메서드에서 던져주는 값이 null 이면 로그인 실패
// bindingResult.reject("login Fail", "아이디 또는 비밀번호가 맞지 않습니다");
System.out.println("로그인 실패");
return "members/login";
}
// 2. null 이외의 값 즉 member 객체라면 로그인 성공 처리
// http 서블릿 세션을 활용하기 위해서는 httpservlerequest 가 필요함 : 세션이 있으면 세션 반환, 없으면 세션 생성
// 이때 request.getSession() 에서 getSession() 의 파라미터안에는 true, false 두가지가 올 수 있음
HttpSession session = request.getSession();
// 세션에 회원 정보(LoginMember) 저장 후 홈으로 반환
session.setAttribute(SessionConst.LOGIN_MEMBER, LoginMember);
/** 이렇게 세션에 별도의 다른 값을 넣어 둘 수 있음 **/
session.setAttribute("memberCode", LoginMember.getCode());
return "redirect:/";
}
@PostMapping("/logout") // http 서블릿 세션 활용 로그아웃
// 세션 종료를 위해서는 sessionManager 에 만들어두었던 expireCookie 를 사용하자
public String loginWithHttpSession(HttpServletRequest request){
HttpSession session = request.getSession(false);
if(session != null){
// invalidate 는 세션을 삭제하는 기능
session.invalidate();
}
return "redirect:/";
}
}
- 구동해서 직접 확인하기
'Java - Spring &&n SpringBoot' 카테고리의 다른 글
Spring Boot && MyBatis without xml : 스프링 부트와 마이 바티스 연동(xml 설정 빼고!) (0) | 2022.07.12 |
---|---|
Spring Web 기본 정리 : 원리, spring 설정, DB 연결해서 데이터 보여주기 (0) | 2022.07.04 |
spring - 로그인 기능 구현하기 (2) 세션으로 로그인 하기 (0) | 2022.01.18 |
spring - 로그인 기능 구현하기 (1) 쿠키 활용, 쿠키의 취약점 (0) | 2022.01.16 |
Spring - AOP 개념 잡기 (0) | 2021.12.27 |
댓글