쿠키와 세션?

seni·2024년 7월 3일

JAVA

목록 보기
33/34

쿠키와 세션

HTTP에 상태 정보를 유지하기 위해 사용된다. 즉, 쿠키와 세션을 통해 서버에서는 클라이언트 별로 인증 및 인가를 할 수 있게 된다

쿠키?

  • 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일
  • 브라우저에서 개발자 도구 -> 애플리케이션 -> 쿠키 보임..

세션

  • 서버에서 일정 시간동안 클라이언트 상태를 유지하기 위해 사용됨.
  • 서버에서 클라이언트 별로 유일무이한 '세션 ID'를 부여한 후 클라이언트 별 필요한 정보를 서버에 저장한다
package com.sparta.springauth.auth;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

@RestController
@RequestMapping("/api")
public class AuthController {

    public static final String AUTHORIZATION_HEADER = "Authorization";      //AUTHORIZATION_HEADER  이름은 상수로 만들어 놓음

    @GetMapping("/create-cookie")
    public String createCookie(HttpServletResponse res) {       //쿠키를 만드는 메서드
        addCookie("Robbie Auth", res);      //저장할 cookievalue? //띄어쓰기=공백이 있으면 쿠키에서 저장할 수 없다고 오류가 남

        return "createCookie";
    }

    @GetMapping("/get-cookie")
    public String getCookie(@CookieValue(AUTHORIZATION_HEADER) String value) {
        // HttpServletRequest에 들어있는 쿠키 중에서 Authorization이라는 이름으로 된 쿠키를
        // @CookieValue(AUTHORIZATION_HEADER)이 애노테이션을 통해서 가지고 온다!
        //@CookieValue 에 우리가 가지고 오고 싶은 (AUTHORIZATION_HEADER) 그 쿠키의 이름을 넣으면
        //String value 이 변수에 해당하는 그 쿠키의 값이 들어감 -> 예상값 "Robbie Auth"
        //Robbie Auth를  cookieValue쪽에 넣었으니깐! 그러면 (@CookieValue(AUTHORIZATION_HEADER) String value)
        //이걸 통해서 value에 해당하는 Robbie Auth 이 값이 들어와야함
        System.out.println("value = " + value);

        return "getCookie : " + value;
    }
    @GetMapping("/create-session")
    public String createSession(HttpServletRequest req) {
        // 세션이 존재할 경우 세션 반환, 없을 경우 새로운 세션을 생성한 후 반환
        HttpSession session = req.getSession(true);

        // 세션에 저장될 정보 Name - Value 를 추가합니다.
        session.setAttribute(AUTHORIZATION_HEADER, "Robbie Auth");

        return "createSession";
    }

    @GetMapping("/get-session")
    public String getSession(HttpServletRequest req) {
        // 세션이 존재할 경우 세션 반환, 없을 경우 null 반환
        HttpSession session = req.getSession(false);

        String value = (String) session.getAttribute(AUTHORIZATION_HEADER); // 가져온 세션에 저장된 Value 를 Name 을 사용하여 가져옵니다.
        System.out.println("value = " + value);

        return "getSession : " + value;
    }

    public static void addCookie(String cookieValue, HttpServletResponse res) {     //쿠키를 저장하는 메서드
        try {
            cookieValue = URLEncoder.encode(cookieValue, "utf-8").replaceAll("\\+", "%20"); // Cookie Value 에는 공백이 불가능해서 encoding 진행
                        //URLEncoder.encode (첫번째에 encode할 값 넣어주고, 타입은 utf-8) replaceAll =전부 다 바꿔준다(공백을 = "//+" 이렇게 표헌하나..? 공백을 "%20"이렇게 바꿔준다)
            //spring에서 cookie 클래스를 만들수 있게끔  Cookie cookie .. 쿠키 클래스!
            Cookie cookie = new Cookie(AUTHORIZATION_HEADER, cookieValue); // (Name-Value)
            cookie.setPath("/");        //set 메서드 사용해서 Path 넣어주고,, MaxAge도..
            cookie.setMaxAge(30 * 60);

            // Response 객체에 Cookie 추가
            res.addCookie(cookie);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}
//HttpServletResponse // 서블릿에서 만들어준 Response 객체에 어떤 데이터를 담으면, 클라이언트로 자연스럽게 반환이 됨.
//우리가 만든 쿠키를 Reponse 객체에 담아야 됨.. , 근데 addCookie 라는 게 이미 존재한다.(쿠키를 만들 공간이 이미 만들어져 있음)
//HttpServletResponse res -> res! // res.addCookie 해서 거기에 우리가 만든 쿠키를 넣어주면 됨 (cookie) -> 그러면 쿠키가 잘 담김.
//우리가 만든 쿠키    Cookie cookie = new Cookie(AUTHORIZATION_HEADER, cookieValue);
//우리가 만든 쿠키    cookie.setPath("/");
//우리가 만든 쿠키    cookie.setMaxAge(30 * 60);

웹 페이지에 한번 로그인 했을때 그 이후로 그 페이지를 들어갈때마다 로그인 하지 않아도 되는 이유는 JWT 때문이야?

웹 페이지에서 한 번 로그인한 이후로 다시 로그인하지 않아도 되는 이유는 여러 가지 방식으로 구현될 수 있습니다. 그중에서 JWT (JSON Web Token)는 가장 일반적이고 많이 사용하는 방법 중 하나입니다. 다음은 JWT를 포함한 몇 가지 방법을 설명합니다.

1. 세션 기반 인증

세션 기반 인증에서는 사용자가 로그인하면 서버가 세션 ID를 생성하고, 이를 클라이언트의 쿠키에 저장합니다. 클라이언트가 서버에 요청을 보낼 때마다 이 쿠키를 함께 전송하여 서버가 세션 ID를 확인하고 사용자를 인증합니다.

장점: 서버 측에서 세션 데이터를 관리하기 때문에 보안성이 높습니다.
단점: 서버가 상태를 유지해야 하므로 서버 리소스를 많이 사용합니다. 또한, 서버가 클러스터링되어 있을 경우 세션 동기화가 필요합니다.

2. 토큰 기반 인증 (JWT)

JWT 기반 인증에서는 사용자가 로그인하면 서버가 JWT를 생성하고 클라이언트에 반환합니다. 클라이언트는 이 JWT를 로컬 스토리지나 쿠키에 저장하고, 서버에 요청을 보낼 때마다 이 토큰을 헤더에 포함시켜 전송합니다. 서버는 이 토큰을 검증하여 사용자를 인증합니다.

장점: 서버는 무상태(Stateless)로 동작하므로 확장성이 높고 서버 간 세션 동기화가 필요 없습니다.
단점: JWT가 클라이언트 측에 저장되므로 토큰 탈취에 대한 보안 이슈가 있을 수 있습니다. 이를 해결하기 위해 HTTPS를 사용하고 토큰 만료 시간을 짧게 설정합니다

3. 쿠키 기반 인증

쿠키 기반 인증에서는 서버가 사용자에게 인증 쿠키를 발급합니다. 이 쿠키는 이후 요청마다 자동으로 서버에 전송되어 사용자를 인증합니다. 세션 기반 인증과 유사하지만, 서버가 상태를 유지하지 않는다는 점이 다릅니다.

장점: 클라이언트 측에서 자동으로 쿠키를 전송하므로 편리합니다.
단점: 쿠키가 탈취될 위험이 있습니다. 이를 막기 위해 Secure, HttpOnly 옵션을 설정합니다.

profile
개발일지

0개의 댓글