세션 사용시 memberId가 계속 같이 넘어오는 현상 문의
685
작성한 질문수 11
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예
[질문 내용]
세션 저장소를 이용해서 클라이언트 요청을 서버로 받아오는데, 계속해서 memberId 값이 함께 넘어오고 있습니다.
코드를 봐도 문제가 없는것처럼 보이는데 제가 원인이 되는 코드를 못찾고 있는 거 같아 문의 드립니다.
어디를 삭제하거나 고치면 되나요?

[SessionManager]
package hello.login.web.session;
import org.springframework.stereotype.Component;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* 세션 관리
*/
@Component
public class SessionManager {
public static final String SESSION_COOKIE_NAME = "mySessionId";
private Map<String, Object> sessionStore = new ConcurrentHashMap<>(); // 세션 저장소
/**
* 세선 생성
* sessionId 생성 (임의의 추정 불가능한 랜덤 값)
* 세션 저장소에 sessionId와 보관할 값 저장
* sessionId로 응답 쿠키를 생성해서 클라이언트에 전달
*/
public void createSession(Object value, HttpServletResponse response){
// 세션 id를 생성하고, 값을 세션 저장소에 저장
String sessionId = UUID.randomUUID().toString();
sessionStore.put(sessionId, value);
// 쿠키 생성
Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
response.addCookie(mySessionCookie);
}
/**
* 세션 조회
*/
public Object getSession(HttpServletRequest request){
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if (sessionCookie == null){
return null;
}
return sessionStore.get(sessionCookie.getValue());
}
/**
* 세션 만료
*/
public void expire(HttpServletRequest request){
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if (sessionCookie != null){
sessionStore.remove(sessionCookie.getValue());
}
}
public Cookie findCookie(HttpServletRequest request, String cookieName){
if (request.getCookies() == null){
return null;
}
return Arrays.stream(request.getCookies())
.filter(cookie -> cookie.getName().equals(cookieName))
.findAny()
.orElse(null);
}
}
[LoginController]
package hello.login.web.login;
import hello.login.domain.login.LoginService;
import hello.login.domain.member.Member;
import hello.login.web.session.SessionManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
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;
@Slf4j
@Controller
@RequiredArgsConstructor
public class LoginController {
private final LoginService loginService;
private final SessionManager sessionManager;
@GetMapping("/login")
public String loginFor(@ModelAttribute("loginForm") LoginForm form){
return "login/loginForm";
}
// @PostMapping("/login")
public String login(@Validated @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){
if (bindingResult.hasErrors()){
return "login/loginForm";
}
Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
if(loginMember == null){
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
return "login/loginForm";
}
// 로그인 성공 처리
// 쿠키에 시간 정보를 주지 않으면 세션 쿠키(브라우저 종료 시 모두 종료)
Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
response.addCookie(idCookie);
return "redirect:/";
}
@PostMapping("/login")
public String loginV2(@Validated @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){
if (bindingResult.hasErrors()){
return "login/loginForm";
}
Member loginMember = loginService.login(form.getLoginId(), form.getPassword());
if(loginMember == null){
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
return "login/loginForm";
}
// 로그인 성공 처리
// 세션 관리자를 통해 세션을 생성하고, 회원 데이터 보관
sessionManager.createSession(loginMember, response);
return "redirect:/";
}
// @PostMapping("logout")
public String logout(HttpServletResponse response){
expireCookie(response, "memberId");
return "redirect:/";
}
@PostMapping("logout")
public String logoutV2(HttpServletRequest request){
sessionManager.expire(request);
return "redirect:/";
}
private static void expireCookie(HttpServletResponse response, String cookieName) {
Cookie cookie = new Cookie(cookieName, null);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
[HomeController]
package hello.login.web;
import hello.login.domain.member.Member;
import hello.login.domain.member.MemberRepository;
import hello.login.web.session.SessionManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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 javax.servlet.http.HttpServletRequest;
@Slf4j
@Controller
@RequiredArgsConstructor
public class HomeController {
private final MemberRepository memberRepository;
private final SessionManager sessionManager;
// @GetMapping("/")
public String home() {
return "home";
}
// @GetMapping("/")
public String homeLogin(@CookieValue(name = "memberId", required = false) Long memberId, Model model){
if(memberId == null){
return "home";
}
// 로그인
Member loingMember = memberRepository.findById(memberId);
if(loingMember == null){
return "home";
}
model.addAttribute("member", loingMember);
return "loginHome";
}
@GetMapping("/")
public String homeLoginV2(HttpServletRequest request, Model model){
// 세션 관리자에 저장된 회원 정보 조회
Member member = (Member) sessionManager.getSession(request);
// 로그인
if(member == null){
return "home";
}
model.addAttribute("member", member);
return "loginHome";
}
}
답변 2
0
안녕하세요 rr8602 님, 인프런 AI 인턴이에요.
세션을 사용하여 클라이언트 요청을 서버로 받아올 때 memberId 값이 계속해서 함께 넘어오는 문제에 대해 도움을 드리겠습니다.
주어진 코드를 확인해보니, memberId 값이 세션 저장소에 저장되어 있지 않고, 쿠키로 전달되는 것을 확인할 수 있습니다. 현재 코드에서 memberId 쿠키를 생성하고 응답에 추가하여 클라이언트로 전송하고 있습니다.
세션은 쿠키를 사용하여 클라이언트의 상태를 유지하는 기술로, 클라이언트와 서버 간의 세션 식별자를 주고받아 관리합니다. 따라서, memberId 값을 함께 유지하는 부분은 코드에서 찾아보지 못하였습니다.
현재 코드에서 memberId 값을 함께 유지하고자 하는 기능이 있다면, 해당 기능을 추가하고 로직을 수정해야 합니다. memberId 값을 세션 저장소에 저장하거나, 세션과 관련된 로직을 구현하여 원하는 기능을 구현할 수 있을 것입니다.
세션과 관련된 로직을 구현하기 위해서는 세션 관리자(SessionManager)를 확인하고 세션 관련 메소드를 추가하거나 수정해야 합니다. 한편, LoginController와 HomeController의 로그인 처리 및 회원 정보 조회 부분도 확인해보셔야 합니다.
기능을 구현하려면 세션과 관련된 메소드를 추가하는 방법을 고려해보시고, 필요하다면 세션 관련 기능을 손쉽게 구현할 수 있는 스프링 세션(Spring Session)을 검토해보시는 것을 추천 드립니다. 스프링 세션은 세션을 효과적으로 관리하고 저장소를 유연하게 사용할 수 있는 기능을 제공합니다.
도움이 되었는지 확인해보시고, 추가적인 도움이 필요하다면 언제든지 문의해주세요. 감사합니다.
이미지 업로드와 db 트랜잭션 묶는법
0
46
1
Could not resolve org.springframework.boot:spring-boot-starter-validation:2.4.4
0
55
2
MessageSourceTest 코드
0
49
1
인터셉터 에러 설정
0
48
1
resolveArgument()메서드 질문
0
58
1
43강 검증1 에서 실패 로직 관련 질문있습니다.
0
60
2
타임리프 3.X 버전 rendering, serializer 에러 해결 방법
2
133
3
스프링 빈에 등록이 안되는거 같은데 어떻게 하면 좋을까요?ㅠㅠ
0
93
3
pdf 오타 문의
0
57
1
ItemUpdateForm 검증 관련 질문입니다.
0
50
1
22page 링크 주소 변경
0
59
2
특정 데이터와 파일을 함께 저장 시, 테이블 구조 질문
0
53
1
섹션3번 수업에 대한 질문입니다.
0
80
2
@Autowired 보다 더 좋은 방법이 어떤 걸까요?
0
87
2
타입컨버터 가 람다랑 비슷해 보이는데 저의 생각이 맞는지?.
0
66
1
자바스크립트 인라인에서 객체 직렬화 시 오류가 납니다
0
143
3
스프링부트 - 오류페이지2 에서 500.html 에서 쓰인 객체 질문
0
65
1
톰캣 에러 페이지가 안보입니다.
0
104
2
apiEceptionController에서 센드 에러 호출하면 안되는지?
0
81
1
세션 타임아웃시 쿠키 삭제 방법이 없나요?
0
118
2
ApiExceptionController 질문드립니다.
0
64
1
셀렉박스 챕터에서 option value에 ==배송 방식 선택== 이것을 넣은 이유가 궁금함, 이렇게 구상해도 되는지?
0
66
1
MemberRepository 필드의 fianl 선언 유무
0
85
2
혹시 index.html 에서는 fragment 사용이 안되는건가요
0
59
1





