HTTP에 상태 정보를 유지하기 위해 사용된다. 즉, 쿠키와 세션을 통해 서버에서는 클라이언트 별로 인증 및 인가를 할 수 있게 된다
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를 포함한 몇 가지 방법을 설명합니다.
세션 기반 인증에서는 사용자가 로그인하면 서버가 세션 ID를 생성하고, 이를 클라이언트의 쿠키에 저장합니다. 클라이언트가 서버에 요청을 보낼 때마다 이 쿠키를 함께 전송하여 서버가 세션 ID를 확인하고 사용자를 인증합니다.
장점: 서버 측에서 세션 데이터를 관리하기 때문에 보안성이 높습니다.
단점: 서버가 상태를 유지해야 하므로 서버 리소스를 많이 사용합니다. 또한, 서버가 클러스터링되어 있을 경우 세션 동기화가 필요합니다.
JWT 기반 인증에서는 사용자가 로그인하면 서버가 JWT를 생성하고 클라이언트에 반환합니다. 클라이언트는 이 JWT를 로컬 스토리지나 쿠키에 저장하고, 서버에 요청을 보낼 때마다 이 토큰을 헤더에 포함시켜 전송합니다. 서버는 이 토큰을 검증하여 사용자를 인증합니다.
장점: 서버는 무상태(Stateless)로 동작하므로 확장성이 높고 서버 간 세션 동기화가 필요 없습니다.
단점: JWT가 클라이언트 측에 저장되므로 토큰 탈취에 대한 보안 이슈가 있을 수 있습니다. 이를 해결하기 위해 HTTPS를 사용하고 토큰 만료 시간을 짧게 설정합니다
쿠키 기반 인증에서는 서버가 사용자에게 인증 쿠키를 발급합니다. 이 쿠키는 이후 요청마다 자동으로 서버에 전송되어 사용자를 인증합니다. 세션 기반 인증과 유사하지만, 서버가 상태를 유지하지 않는다는 점이 다릅니다.
장점: 클라이언트 측에서 자동으로 쿠키를 전송하므로 편리합니다.
단점: 쿠키가 탈취될 위험이 있습니다. 이를 막기 위해 Secure, HttpOnly 옵션을 설정합니다.