• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

세션 사용시 memberId가 계속 같이 넘어오는 현상 문의

23.10.17 00:41 작성 조회수 471

0

[질문 템플릿]
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 (requ
est.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

·

답변을 작성해보세요.

1

OMG님의 프로필

OMG

2023.10.20

안녕하세요. rr8602님, 공식 서포터즈 OMG입니다.

이름이 memberId 인 쿠키를 마우스 우클릭하여 삭제 후 실행해도 동일할까요?

감사합니다.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.10.19

안녕하세요 rr8602 님, 인프런 AI 인턴이에요.
세션을 사용하여 클라이언트 요청을 서버로 받아올 때 memberId 값이 계속해서 함께 넘어오는 문제에 대해 도움을 드리겠습니다.

주어진 코드를 확인해보니, memberId 값이 세션 저장소에 저장되어 있지 않고, 쿠키로 전달되는 것을 확인할 수 있습니다. 현재 코드에서 memberId 쿠키를 생성하고 응답에 추가하여 클라이언트로 전송하고 있습니다.

세션은 쿠키를 사용하여 클라이언트의 상태를 유지하는 기술로, 클라이언트와 서버 간의 세션 식별자를 주고받아 관리합니다. 따라서, memberId 값을 함께 유지하는 부분은 코드에서 찾아보지 못하였습니다.

현재 코드에서 memberId 값을 함께 유지하고자 하는 기능이 있다면, 해당 기능을 추가하고 로직을 수정해야 합니다. memberId 값을 세션 저장소에 저장하거나, 세션과 관련된 로직을 구현하여 원하는 기능을 구현할 수 있을 것입니다.

세션과 관련된 로직을 구현하기 위해서는 세션 관리자(SessionManager)를 확인하고 세션 관련 메소드를 추가하거나 수정해야 합니다. 한편, LoginController와 HomeController의 로그인 처리 및 회원 정보 조회 부분도 확인해보셔야 합니다.

기능을 구현하려면 세션과 관련된 메소드를 추가하는 방법을 고려해보시고, 필요하다면 세션 관련 기능을 손쉽게 구현할 수 있는 스프링 세션(Spring Session)을 검토해보시는 것을 추천 드립니다. 스프링 세션은 세션을 효과적으로 관리하고 저장소를 유연하게 사용할 수 있는 기능을 제공합니다.

도움이 되었는지 확인해보시고, 추가적인 도움이 필요하다면 언제든지 문의해주세요. 감사합니다.