본문 바로가기
Java

[JAVA] 쿠키 세션 관리하기

by teamnova 2023. 11. 23.

오늘은 자바로 쿠키와 세션을 관리해보겠습니다.

 

 

//SimpleHttpServer.java

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Logger;

public class SimpleHttpServer {
    private static final Logger logger = Logger.getLogger(SimpleHttpServer.class.getName());

    public static void main(String[] args) throws Exception {
        // 서버 생성 및 포트 8000에서 시작
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        server.createContext("/test", new TestHandler());
        server.setExecutor(null);
        logger.info("       Server started at port 8000.");
        server.start();
    }

    static class TestHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            // HTTP 요청 메서드 기록
            logger.info("       Received a " + exchange.getRequestMethod() + " request.");

            // 요청 메서드에 따른 핸들러 호출
            String method = exchange.getRequestMethod();
            if ("GET".equalsIgnoreCase(method)) {
                handleGet(exchange);
            } else if ("POST".equalsIgnoreCase(method)) {
                handlePost(exchange);
            } else if ("PUT".equalsIgnoreCase(method)) {
                handlePut(exchange);
            } else if ("DELETE".equalsIgnoreCase(method)) {
                handleDelete(exchange);
            }
        }

        private void handleGet(HttpExchange exchange) throws IOException {
            // 쿠키에서 세션 ID 검색
            String sessionId = getCookie(exchange, "SESSIONID");

            // 세션 ID 없거나 세션 미존재 시 새로운 세션 생성
            if (sessionId == null || SessionManager.getSession(sessionId) == null) {
                sessionId = SessionManager.createSession();
                setCookie(exchange, "SESSIONID", sessionId);
                logger.info("       Created new session for GET request: " + sessionId);
            }

            // 세션 데이터 응답 준비 및 전송
            Map<String, Object> userSession = SessionManager.getSession(sessionId);
            String response = "Read session with ID: " + sessionId + ", Data: " + userSession;
            logger.info("       Responding to GET request: " + response);
            sendResponse(exchange, response, 200);
        }

        private void handlePost(HttpExchange exchange) throws IOException {
            // 새로운 세션 생성
            String sessionId = SessionManager.createSession();
            setCookie(exchange, "SESSIONID", sessionId);

            // 세션 생성 응답 준비 및 전송
            String response = "Created new session with ID: " + sessionId;
            logger.info("       Responding to POST request: " + response);
            sendResponse(exchange, response, 201);
        }

        private void handlePut(HttpExchange exchange) throws IOException {
            // 쿠키에서 세션 ID 검색
            String sessionId = getCookie(exchange, "SESSIONID");

            // 세션 존재 시 데이터 업데이트
            if (sessionId != null && SessionManager.getSession(sessionId) != null) {
                SessionManager.getSession(sessionId).put("updated", "true");

                String response = "Updated session with ID: " + sessionId;
                logger.info("       Responding to PUT request: " + response);
                sendResponse(exchange, response, 200);
            } else {
                // 세션 미존재 시 에러 응답 전송
                String response = "Session not found";
                logger.warning("Session not found for PUT request.");
                sendResponse(exchange, response, 404);
            }
        }

        private void handleDelete(HttpExchange exchange) throws IOException {
            // 쿠키에서 세션 ID 검색
            String sessionId = getCookie(exchange, "SESSIONID");

            // 세션 존재 시 삭제
            if (sessionId != null) {
                SessionManager.deleteSession(sessionId);

                String response = "Deleted session with ID: " + sessionId;
                logger.info("       Responding to DELETE request: " + response);
                sendResponse(exchange, response, 200);
            } else {
                // 세션 미존재 시 에러 응답 전송
                String response = "Session not found";
                logger.warning("Session not found for DELETE request.");
                sendResponse(exchange, response, 404);
            }
        }

        // HTTP 응답 전송 메서드
        private void sendResponse(HttpExchange exchange, String response, int statusCode) throws IOException {
            exchange.sendResponseHeaders(statusCode, response.length());
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }

        // 쿠키 설정 메서드
        private void setCookie(HttpExchange exchange, String cookieName, String cookieValue) {
            exchange.getResponseHeaders().add("Set-Cookie", cookieName + "=" + cookieValue + "; Path=/; HttpOnly");
            logger.info("       Set cookie: " + cookieName + "=" + cookieValue);
        }

        // 쿠키 검색 메서드
        private String getCookie(HttpExchange exchange, String cookieName) {
            List<String> cookies = exchange.getRequestHeaders().get("Cookie");
            if (cookies == null) return null;

            for (String cookie : cookies) {
                String[] cookieParts = cookie.split(";");
                for (String cookiePart : cookieParts) {
                    String[] keyValue = cookiePart.trim().split("=");
                    if (keyValue.length == 2 && keyValue[0].equals(cookieName)) {
                        return keyValue[1];
                    }
                }
            }

            return null;
        }
    }
}

// 세션 관리 유틸리티 클래스
class SessionManager {
    private static final Logger logger = Logger.getLogger(SessionManager.class.getName());
    private static final Map<String, Object> sessions = new HashMap<>();
    private static final Random random = new Random();

    // 세션 생성 메서드
    public static String createSession() {
        String sessionId = String.valueOf(random.nextLong());
        sessions.put(sessionId, new HashMap<String, Object>());
        logger.info("       Session created with ID: " + sessionId);
        return sessionId;
    }

    // 세션 검색 메서드
    public static Map<String, Object> getSession(String sessionId) {
        Map<String, Object> session = (Map<String, Object>) sessions.get(sessionId);
        if (session != null) {
            logger.info("       Retrieved session with ID: " + sessionId);
        } else {
            logger.warning("No session found for ID: " + sessionId);
        }
        return session;
    }

    // 세션 삭제 메서드
    public static void deleteSession(String sessionId) {
        sessions.remove(sessionId);
        logger.info("       Deleted session with ID: " + sessionId);
    }
}

 

//SimpleHttpClient.java

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

public class SimpleHttpClient {
    // 쿠키 저장소
    private static final Map<String, String> cookieStore = new HashMap<>();
    // 로거 인스턴스
    private static final Logger logger = Logger.getLogger(SimpleHttpClient.class.getName());

    public static void main(String[] args) throws Exception {
        // HTTP 클라이언트 인스턴스 생성
        HttpClient client = HttpClient.newHttpClient();
        // GET 요청 전송
        sendGetRequest(client);
        // POST 요청 전송
        sendPostRequest(client);
        // PUT 요청 전송
        sendPutRequest(client);
        // DELETE 요청 전송
        sendDeleteRequest(client);
    }

    private static void sendGetRequest(HttpClient client) throws Exception {
        // GET 요청 로그 기록
        logger.info("       GET 요청 전송 중...");
        // GET 요청 객체 생성
        HttpRequest getRequest = buildRequestWithCookies("http://localhost:8000/test", "GET");
        // GET 요청 응답 수신
        HttpResponse<String> getResponse = client.send(getRequest, HttpResponse.BodyHandlers.ofString());
        // 응답에서 쿠키 저장
        storeCookies(getResponse.headers());
        // 응답 로그 기록
        logger.info("       GET 응답 수신: " + getResponse.body());
    }

    private static void sendPostRequest(HttpClient client) throws Exception {
        // POST 요청 로그 기록
        logger.info("       POST 요청 전송 중...");
        // POST 요청 객체 생성
        HttpRequest postRequest = buildRequestWithCookies("http://localhost:8000/test", "POST");
        // POST 요청 응답 수신
        HttpResponse<String> postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString());
        // 응답에서 쿠키 저장
        storeCookies(postResponse.headers());
        // 응답 로그 기록
        logger.info("       POST 응답 수신: " + postResponse.body());
    }

    private static void sendPutRequest(HttpClient client) throws Exception {
        // PUT 요청 로그 기록
        logger.info("       PUT 요청 전송 중...");
        // PUT 요청 객체 생성
        HttpRequest putRequest = buildRequestWithCookies("http://localhost:8000/test", "PUT");
        // PUT 요청 응답 수신
        HttpResponse<String> putResponse = client.send(putRequest, HttpResponse.BodyHandlers.ofString());
        // 응답에서 쿠키 저장
        storeCookies(putResponse.headers());
        // 응답 로그 기록
        logger.info("       PUT 응답 수신: " + putResponse.body());
    }

    private static void sendDeleteRequest(HttpClient client) throws Exception {
        // DELETE 요청 로그 기록
        logger.info("       DELETE 요청 전송 중...");
        // DELETE 요청 객체 생성
        HttpRequest deleteRequest = buildRequestWithCookies("http://localhost:8000/test", "DELETE");
        // DELETE 요청 응답 수신
        HttpResponse<String> deleteResponse = client.send(deleteRequest, HttpResponse.BodyHandlers.ofString());
        // 응답에서 쿠키 저장
        storeCookies(deleteResponse.headers());
        // 응답 로그 기록
        logger.info("       DELETE 응답 수신: " + deleteResponse.body());
    }

    private static HttpRequest buildRequestWithCookies(String url, String method) {
        // 요청 빌더 초기화
        HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url));
        // 요청 빌드 로그 기록
        logger.info("       URL: " + url + ", 메서드: " + method + "로 요청 객체 생성 중...");

        // 쿠키 추가 로직
        if (!cookieStore.isEmpty()) {
            builder.header("Cookie", cookieStore.entrySet().stream()
                    .map(entry -> entry.getKey() + "=" + entry.getValue())
                    .reduce((c1, c2) -> c1 + "; " + c2).orElse(""));
            // 쿠키 추가 로그 기록
            logger.info("       요청에 쿠키 추가: " + cookieStore);
        }

        // HTTP 메서드 설정 로직
        if ("POST".equals(method)) {
            builder.POST(HttpRequest.BodyPublishers.noBody());
        } else if ("PUT".equals(method)) {
            builder.PUT(HttpRequest.BodyPublishers.noBody());
        } else if ("DELETE".equals(method)) {
            builder.DELETE();
        } else {
            builder.GET();
        }

        return builder.build();
    }

    private static void storeCookies(HttpHeaders headers) {
        // 응답 헤더에서 'Set-Cookie' 값 추출
        List<String> setCookies = headers.allValues("Set-Cookie");
        for (String setCookie : setCookies) {
            String[] cookieParts = setCookie.split(";");
            if (cookieParts.length > 0) {
                String[] keyValue = cookieParts[0].trim().split("=");
                if (keyValue.length == 2) {
                    // 쿠키 저장소에 쿠키 저장
                    cookieStore.put(keyValue[0], keyValue[1]);
                    // 쿠키 저장 로그 기록
                    logger.info("       쿠키 저장: " + keyValue[0] + ", 값: " + keyValue[1]);
                }
            }
        }
    }
}