HTTP Servlet 을 통한 Session 사용하기

알파로그·2023년 3월 16일
0

Spring Boot

목록 보기
7/57

✏️ Rq 계층

  • Http Servlet 의 Request 와 Response 관련 로직을 별도의 Class 인 Rq 로 분리했다.
package com.ll.basic1.cookie;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;

@Component
@RequestScope  // 빼먹지 않게 주의!
@RequiredArgsConstructor
public class Rq {

    private final HttpServletRequest req;
    private final HttpServletResponse resp;

📍 Session 생성

  • Session 이름과 value 를 매개변수로 받아 Session 을 생성한다.
  • 지금은 공부하는 단계라 Session 이름은 “loginedMemberId" 로 통일해서 작업할 예정이다.
  • value 는 클라이언트의 id 를 사용한다.
  • ⚠️ id 는 int 타입으로 사용할 수 없다.
    • 간단한 실습일줄 알고 Entity 에서 int 로 선언했다 논리에러가 발생해 한참 고생했다..
    • 아무리 간단한 프로젝트여도 long 으로 선언해주자..
    //-- 세션 생성 --//
    public void setSession(String name, long value) {
        HttpSession session = req.getSession();
        session.setAttribute(name, value);
    }

📍 Session 조회

  • 세션의 이름과 클라이언트의 id 값을 매개변수로 받는다.
  • V1, V2 버전이 있는데 V1 은 id 를 반환하고, V2 는 String 타입을 반환한다.
    • 학습 내용에서는 V1 만 쓰인다.
  • Controller 에서는 long 값에 0 을 넣어 전달하고,
    Session 을 찾지 못할경우 0 을 그대로 반환해 Session 이 없는 클라이언트를 식별하고,
    Session 이 있다면 세션 값을 반환해 id 값으로 클라이언트를 식별하는 방식이다.
//-- 세션 조회 V1 --//
    public long getSessionAsLong(String name, long defaultValue) {
        try {
            long value = (long) req.getSession().getAttribute(name);
            return value;
        } catch (Exception e) {
            return defaultValue;
        }
    }

    //-- 새션 조회 V2 --//
    private String getSessionAsStr(String name, String defaultValue) {
        try {
            String value = (String) req.getSession().getAttribute(name);
            if (value == null) return defaultValue;
            return value;
        } catch (Exception e) {
            return defaultValue;
        }
    }

📍 Session 간편 확인

  • getSession 의 반환 값을 통해 Session 을 갖고있는 클라이언트인지를 확인하는 로직
public boolean isLogined() {
        long loginedMemberId = getSessionAsLong("loginedMemberId", 0);
        return loginedMemberId > 0;
    }

📍 Session 삭제

  • 세션 이름을 매개변수로 받아 세션을 찾지 못하면 false ,
    찾는다면 삭제후 ture 를 반환하는 로직이다.
    //-- 세션 삭제 --//
    public boolean removeSession(String name) {
        HttpSession session = req.getSession();

        if (session.getAttribute(name) == null)
            return false;

        session.removeAttribute(name);
        return true;
    }

✏️ Controller 계층

  • 지난시간에 만든 Cookie 로 구현했던 로직을 Session 으로 변경하면 된다.

📍 Log in - Session 생성

  • 매개변수의 @RequestParam 을 생략했다.
  • Service 의 login 기능이 완료된뒤 참조했던 쿠키생성 대신 세션 생성을 참조한다.
    • 처음 로직을 만들 때 쿠키와 세션 작업을 할 줄 몰랐고,
      SSR 도 할 지 몰랐기 때문에 Service 로직의 반환값이 DTO 로 되어있다.
    • 시간관계상 리팩토링을 하지못해 매끄럽지 못했다.
    //-- 파라미터로 로그인 하기 --//
    // http://localhost:8080/member/login?username=홍길동&password=1234
    @PostMapping("/member/login")
    public String doLogin(String username, int password, Model model) {

        MemberDto dto = service.login(username, password);
        Member member = dto.getMember();

        rq.setSession("loginedMemberId", member.getId());

        model.addAttribute("member", member);
        return "usr/member/login";
    }

📍 개인정보 확인하기 - Session 조회

  • 세션의 존재여부를 확인하고, 없다면 “F-1” 을 반환한다.
  • 있다면 Service 로 회원정보를 조회해 반환한다.
    //-- 사용자 정보 확인하기 --//
    // http://localhost:8080/member/me
    @GetMapping("/member/me")
    @ResponseBody
    public MemberDto showMe() {
        long loginedMemberId = rq.getSessionAsLong("loginedMemberId", 0);
        boolean isLogined = loginedMemberId > 0;

        if (!isLogined)
            return new MemberDto("F-1", "로그인후 이용해 주세요.");

        Member member = service.findOne(loginedMemberId);

        return new MemberDto("S-1", "당신의 username(은)는 " + member.getName() +" 입니다.");
    }

📍Log out - Session 삭제

  • 세션이 없다면 “S-2” 있다면 종료후 “S-1” 을 반환
    //-- 로그 아웃 하기 --//
    // http://localhost:8080/member/logout
    @GetMapping("/member/logout")
    @ResponseBody
    public MemberDto logout() {
        boolean result = rq.removeSession("loginedMemberId");

        if (!result)
            return new MemberDto("S-2", "이미 로그아웃 상태입니다.");

        else {
            return new MemberDto("S-1", "로그아웃 되었습니다.");
        }
    }
profile
잘못된 내용 PR 환영

0개의 댓글