DevLog ๐Ÿ˜ถ

[Spring] ์ƒํ’ˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ์„ธ์…˜์œผ๋กœ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋ณธ๋ฌธ

Back-end/Spring

[Spring] ์ƒํ’ˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ์„ธ์…˜์œผ๋กœ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

dolmeng2 2022. 8. 23. 22:14

๊น€์˜ํ•œ ๋‹˜์˜ '์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ '์„ ๋ณด๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ๐Ÿ˜Š

 

์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์›น ๊ธฐ์ˆ ์„ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์ดํ•ดํ•˜๊ณ , ์™„์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. MVC 2ํŽธ์—์„œ๋Š” MVC 1ํŽธ์˜ ํ•ต์‹ฌ ์›๋ฆฌ์™€ ๊ตฌ์กฐ ์œ„์— ์‹ค๋ฌด ์›น ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ํ™œ์šฉ ๊ธฐ์ˆ ๋“ค์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ

www.inflearn.com


- ์ง€๋‚œ ํฌ์ŠคํŒ…๊ณผ ์ด์–ด์ง‘๋‹ˆ๋‹ค :D

 

[Spring] ์ƒํ’ˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ํšŒ์›๊ฐ€์ž… / ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ๋กœ์ง ์ถ”๊ฐ€ํ•˜๊ธฐ, ์ฟ ํ‚ค๋ฅผ ํ†ตํ•œ ์‹๋ณ„ ์ฒ˜๋ฆฌ

๊น€์˜ํ•œ ๋‹˜์˜ '์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ '์„ ๋ณด๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ๐Ÿ˜Š ์Šคํ”„๋ง MVC 2ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ™œ์šฉ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์›น ๊ธฐ์ˆ ์„

cl8d.tistory.com


 

| ์„ธ์…˜์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ (์ง์ ‘ ๊ตฌํ˜„)

- ์„ธ์…˜์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ์„ ์ฒ˜๋ฆฌํ•ด๋ณด์ž.

- ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ์ „์†กํ•˜๋ฉด, ์„œ๋ฒ„์—์„œ ํ•ด๋‹น ์ •๋ณด๋ฅผ ์ฒดํฌํ•˜์—ฌ ์‚ฌ์šฉ์ž๋ฅผ ์กฐํšŒํ•œ๋‹ค.

- ์„œ๋ฒ„์—์„œ๋Š” ์„ธ์…˜ID๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. (์ถ”์ • ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฐ’์œผ๋กœ ๋žœ๋คํ•˜๊ฒŒ ์ƒ์„ฑ)

- ์ƒ์„ฑ ํ›„, ํ•ด๋‹น ์„ธ์…˜ ID๋ฅผ ํ‚ค ๊ฐ’์œผ๋กœ ํ•˜์—ฌ ๋ฉค๋ฒ„๋ฅผ ์ €์žฅํ•ด๋‘”๋‹ค.

- ์„œ๋ฒ„๋Š” ์„ธ์…˜ Id๋งŒ ์ฟ ํ‚ค์— ๋‹ด์•„ ์ „๋‹ฌํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ๋Š” ์ด๋ฅผ ๋ฐ›์•„์„œ ๋ณด๊ด€ํ•˜๋ฉฐ ์š”์ฒญ ์‹œ ํ•จ๊ป˜ ์ „๋‹ฌํ•œ๋‹ค.

โญ ๊ฒฐ๊ตญ, ์ค‘์š”ํ•œ ๊ฐ’์€ ์ฟ ํ‚ค์— ๋„ฃ์–ด์„œ ์ „์†กํ•˜์ง€ ์•Š๋Š” ๊ฒƒ.

 

[SessionManager.java]

@Component
public class SessionManager {
    public static final String SESSION_COOKIE = "mySessionId";
    private Map<String, Object> store = new ConcurrentHashMap<>();

    public void createSession(Object value, HttpServletResponse response) {
        String sessionId = UUID.randomUUID().toString();
        store.put(sessionId, value);
        Cookie mySessionCookie = new Cookie(SESSION_COOKIE, sessionId);
        mySessionCookie.setPath("/");
        response.addCookie(mySessionCookie);
    }

    public Object getSession(HttpServletRequest request) {
        Cookie sessionCookie = findCookie(request, SESSION_COOKIE);
        if (sessionCookie == null) {
            return null;
        }
        return store.get(sessionCookie.getValue());
    }

    public void expire(HttpServletRequest request) {
        Cookie sessionCookie = findCookie(request, SESSION_COOKIE);
        if (sessionCookie != null) {
            store.remove(sessionCookie.getValue());
        }
    }

    private Cookie findCookie(HttpServletRequest request, String cookieName) {
        if (request.getCookies() == null) {
            return null;
        }
        return Arrays.stream(request.getCookies())
                .filter(cookie -> cookie.getName().equals(cookieName))
                .findAny()
                .orElse(null);
    }
}

- ์„ธ์…˜ ์ƒ์„ฑ ๋ฐ ์กฐํšŒ, ๋งŒ๋ฃŒ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

- ์ฟ ํ‚ค์— memberId ๋Œ€์‹  UUID๋ฅผ ํ†ตํ•ด ๋žœ๋ค์œผ๋กœ ์ƒ์„ฑํ•œ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๊ณ , ๋ณ„๋„์˜ ์„ธ์…˜ ์ €์žฅ์†Œ๋ฅผ map์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

- ๋งŒ๋ฃŒ ์‹œ์—๋Š” ์„ธ์…˜ ์ €์žฅ์†Œ์—์„œ ์—†์• ๋ฒ„๋ฆฐ๋‹ค.

- ์กฐํšŒ ์‹œ์—๋Š” HttpServlet์—์„œ ์ฟ ํ‚ค ์ค‘ "mySessionId"์ธ ์ฟ ํ‚ค๋ฅผ ์ฐพ์•„์„œ ํ•ด๋‹น ์ฟ ํ‚ค์˜ value ๊ฐ’์„ ๋ฆฌํ„ดํ•ด์ค€๋‹ค.

 

cf) ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์งค ๋•Œ HttpServletRequest, HttpServletResponse๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํ†ต์€ MockHttpServletRequest, MockHttpServletResponse๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค!

 

[LMemberController.java]

@PostMapping("/login")
public String login(@Valid @ModelAttribute("loginForm") LMemberLoginRequest loginRequest,
                    BindingResult bindingResult, HttpServletResponse response) {
    if(bindingResult.hasErrors()) {
        return "login/members/loginForm";
    }

    LMember loginMember = service.login(loginRequest);
    if(loginMember == null) {
        bindingResult.reject("loginFail", "์•„์ด๋”” ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
        return "login/members/loginForm";
    }

    sessionManager.createSession(loginMember, response);
    return "redirect:/login/";
}

@PostMapping("/logout")
public String logout(HttpServletRequest request) {
    sessionManager.expire(request);
    return "redirect:/login/";
}

- ๋‹ค์Œ์ฒ˜๋Ÿผ ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ ๋กœ์ง์—์„œ ์„ธ์…˜์„ ํ™œ์šฉํ•ด์ค€๋‹ค.

 

[LHomeController.java] - ์ˆ˜์ •

@GetMapping("/")
public String home(HttpServletRequest request, Model model) {
    LMember member = (LMember) sessionManager.getSession(request);
    if(member == null) {
        return "login/home";
    }
    model.addAttribute("member", member);
    return "login/loginHome";
}

- ๊ธฐ์กด์—๋Š” ์ฟ ํ‚ค์—์„œ ๊ฐ’์„ ๊บผ๋‚ด์„œ ์ผ์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ์„ธ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด map์— ์ €์žฅ๋˜์–ด ์žˆ๋Š”์ง€ ํŒ๋‹จํ•œ๋‹ค.

- ๊ตณ์ด ์ฟ ํ‚ค์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ์ค„์ด์ง€ ์•Š์•„๋„, map์— ์—†์œผ๋ฉด ๋กœ๊ทธ์•„์›ƒ์ด๋ผ๊ณ  ํŒ๋‹จํ•˜๊ธฐ.


 

| ์„ธ์…˜์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ (์„œ๋ธ”๋ฆฟ ์„ธ์…˜)

- ์„œ๋ธ”๋ฆฟ์—์„œ ์ œ๊ณตํ•˜๋Š” HttpSession์„ ํ†ตํ•ด์„œ ์šฐ๋ฆฌ์˜ ์›น ์‚ฌ์ดํŠธ์— ์ ์šฉํ•ด๋ณด์ž.

- ์„œ๋ธ”๋ฆฟ์„ ํ†ตํ•ด HttpSession์„ ์ƒ์„ฑํ•˜๋ฉด ์ฟ ํ‚ค ์ด๋ฆ„์ด JSESSIONID, ๊ฐ’์ด ๋žœ๋คํ•œ ๊ฐ’์ธ ์ฟ ํ‚ค๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.

 

- ์ฆ‰, ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์„ธ์…˜์„ ์ƒ์„ฑํ•˜๊ณ , ์‘๋‹ต ํ—ค๋”์— ์„ธ์…˜ ID๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. (JSESSIONID๋Š” ํ†ฐ์บฃ์ด ์ƒ์„ฑ, ์„ธ์…˜ ์ €์žฅ์†Œ๋ฅผ ํ†ฐ์บฃ์ด ๊ด€๋ฆฌ)

-> ์ดํ›„ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ ์‘๋‹ต์„ ํ•ด์ฃผ๋Š” ํ˜•์‹์ด๋‹ค.

- ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต์˜ ์ฟ ํ‚ค๋กœ JessionId๊ฐ€ ๋‹ด๊ฒจ์ ธ์„œ ์ „๋‹ฌ๋˜๋Š” ํ˜•์‹ (์ด๊ฒƒ๋„ ํ†ฐ์บฃ์ด ํ•ด์ค€๋‹ค)

 

[LMemberController.java]

@PostMapping("/login")
public String login(@Valid @ModelAttribute("loginForm") LMemberLoginRequest loginRequest,
                    BindingResult bindingResult, HttpServletRequest request) {
    if(bindingResult.hasErrors()) {
        return "login/members/loginForm";
    }

    LMember loginMember = service.login(loginRequest);
    if(loginMember == null) {
        bindingResult.reject("loginFail", "์•„์ด๋”” ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
        return "login/members/loginForm";
    }

    HttpSession session = request.getSession();
    session.setAttribute("loginMember", loginMember);
    return "redirect:/login/";
}

@PostMapping("/logout")
public String logout(HttpServletRequest request) {
    HttpSession session = request.getSession();
    if(session != null) {
        session.invalidate();
    }
    return "redirect:/login/";
}

getSession์„ ํ†ตํ•ด ๊ธฐ์กด ์„ธ์…˜์ด ์กด์žฌํ•˜๋ฉด ๋ฐ˜ํ™˜, ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•œ๋‹ค. (์ƒ์„ฑ ์‹œ ์‚ฌ์šฉ)

์ด๋•Œ, getSession(false)๋กœ ํ•˜๋ฉด ์„ธ์…˜์ด ์—†์„ ๋•Œ ์ƒˆ๋กœ์šด ์„ธ์…˜์„ ์ƒ์„ฑํ•˜์ง€๋Š” ์•Š๊ณ  null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (์กฐํšŒ ์‹œ ์‚ฌ์šฉ)

 

์ฆ‰, request ์ •๋ณด์—์„œ ์–ป์–ด์˜จ UUID ๊ฐ’์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ์ฟ ํ‚ค์˜ value๋ฅผ ๋ณด๊ณ  ์„ธ์…˜ ์ €์žฅ์†Œ์—์„œ ๋™์ผํ•œ JsessionId ๊ฐ’์ด ์žˆ๋Š”์ง€ ์ฐพ๋Š”๋‹ค.

๋™์ผํ•œ ๊ฐ’์ด ์žˆ์œผ๋ฉด ํ•ด๋‹น session์„ ๊ฐ€์ ธ์˜ค๊ณ , ์—†์œผ๋ฉด ํ•ด๋‹น session์„ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

session์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€ํ•˜๊ธฐ ์œ„ํ•ด setAttribute()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

name์—๋Š” ์ƒ์ˆ˜๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋” ์ข‹์ง€๋งŒ ์šฐ์„  ์ €๋ ‡๊ฒŒ String์œผ๋กœ ๋ฐ•์•˜๋‹ค...

session์˜ key์—๋Š” "loginMember"๋ฅผ, value์—๋Š” ์‹ค์ œ member ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค.

์ดํ›„, sessionId๋ฅผ ํ†ตํ•ด session์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ session์˜ ํ‚ค๋ฅผ ํ†ตํ•ด ๋‚ด๋ถ€์˜ member ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

์ดํ›„, ๋กœ๊ทธ์•„์›ƒ ์‹œ ์„ธ์…˜์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด์„œ session.invalidate()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

๐Ÿšฉ ์Œ... ์ข€ ๋ณต์žกํ•˜์ง€๋งŒ ๋‹ค์‹œ ์ •๋ฆฌํ•˜์ž๋ฉด,

[ํ†ฐ์บฃ์ด ๊ด€๋ฆฌํ•˜๋Š” ์„ธ์…˜ ์ €์žฅ์†Œ]

key - JsessionId, value - Session ํ˜•ํƒœ๋กœ ์ €์žฅ.

- ์—ฌ๊ธฐ์„œ value ๊ฐ’์€ request.getSession์œผ๋กœ ์–ป์€ ๊ฐ’์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

[์„ธ์…˜ ์ €์žฅ์†Œ์˜ value์— ์ €์žฅ๋œ ๊ฐ ์„ธ์…˜]

key - loginMember, value - ์‹ค์ œ Member ๊ฐ์ฒด

- setAttribute๋ฅผ ํ†ตํ•ด ๋„ฃ์–ด์ค€ ๊ฐ’!

 

์ด๋Ÿฐ ์‹์œผ๋กœ ๋˜์–ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค!

 

[LHomeController.java]

@GetMapping("/")
public String home(HttpServletRequest request, Model model) {
    HttpSession session = request.getSession(false);
    if (session == null) {
        return "login/home";
    }
    LMember loginMember = (LMember) session.getAttribute("loginMember");
    if (loginMember == null) {
        return "login/home";
    }
    model.addAttribute("member", loginMember);
    return "login/loginHome";
}

- ์„ธ์…˜ ์กฐํšŒ ์‹œ์—๋Š” getSession(false)๋ฅผ ํ†ตํ•ด ์กฐํšŒํ•œ๋‹ค. ์„ธ์…˜ ์ž์ฒด๊ฐ€ ์—†์œผ๋ฉด ๋กœ๊ทธ์•„์›ƒ์ด ๋˜์–ด์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•œ๋‹ค.

- ์„ธ์…˜์ด ์žˆ๋‹ค๋ฉด ๊ฐ ์„ธ์…˜์— ์ €์žฅ๋œ ํšŒ์› ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

- ์ด๋•Œ, ํšŒ์› ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด ์—ญ์‹œ ๋กœ๊ทธ์•„์›ƒ์ด ๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

 

cf) ์ด์ƒํƒœ๋กœ ์ง„ํ–‰ํ•˜๋ฉด url์— ์ž๋™์œผ๋กœ ;jsessionId=302948902384๊ฐ€ ๋ถ™์–ด์„œ 404 ์—๋Ÿฌ๊ฐ€ ๋‚˜ํƒ€๋‚œ๋‹ค.

๊ทธ๋ž˜์„œ, ์Šคํ”„๋ง ๋‚ด๋ถ€์˜ config์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

 

[WebMvcConfig.java]

@Bean
public ServletContextInitializer configSession() {
    return servletContext -> {
        servletContext.setSessionTrackingModes(
                Collections.singleton(SessionTrackingMode.COOKIE));
        servletContext.getSessionCookieConfig()
                .setHttpOnly(true);
    };
}

๐Ÿšฉ HTTP Protocol์€ stateless ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํ†ฐ์บฃ ๊ฐ™์€ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์„ธ์…˜ ๊ด€๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

- ์ด๋•Œ, ์ฟ ํ‚ค๋‚˜ URL Rewriting์„ ํ†ตํ•ด์„œ ์ฃผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

- ์ง€๊ธˆ ์œ„์˜ ๊ฒฝ์šฐ URL Rewriting์ด ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ์ธ๋ฐ, ์ด๋•Œ ํ†ฐ์บฃ์ด ์ฒ˜๋ฆฌํ•˜๋Š” Coyote Http11Process๊ฐœ CoyoteAdapter๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค

 

[CoyoteAdapter.java]

protected boolean postParseRequest(org.apache.coyote.Request req, Request request,
                                       org.apache.coyote.Response res, Response response) throws IOException, ServletException {

        ...

        String sessionID;
        if (request.getServletContext().getEffectiveSessionTrackingModes()
                .contains(SessionTrackingMode.URL)) {

            // Get the session ID if there was one
            sessionID = request.getPathParameter(
                    SessionConfig.getSessionUriParamName(
                            request.getContext()));
            if (sessionID != null) {
                request.setRequestedSessionId(sessionID);
                request.setRequestedSessionURL(true);
            }
        }

        // Look for session ID in cookies and SSL session
        try {
            parseSessionCookiesId(request);
        } catch (IllegalArgumentException e) {
            // Too many cookies
            if (!response.isError()) {
                response.setError();
                response.sendError(400);
            }
            return true;
        }
        parseSessionSslId(request);
        ...
}

- ์œ„ ๋ฉ”์„œ๋“œ์—์„œ getEffectiveSessionTrackingModes()์—์„œ URL mode๋ฅผ ํฌํ•จํ•˜๋ฉด, ํ•ด๋‹น URL์—์„œ ์„ธ์…˜ ID๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ ์ฐพ๋Š”๋‹ค.

- ์„ธ์…˜ ID๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด request์— session์„ ์ง„ํ–‰ํ•ด์ค€๋‹ค. 

- ์ดํ›„, try๋ฌธ์—์„œ ์ฟ ํ‚ค์— ์ €์žฅ๋œ ์„ธ์…˜ID๋ฅผ ์ฐพ๋Š”๋‹ค.

 

[parseSessionCookiesId.java]

protected void parseSessionCookiesId(Request request) {
    Context context = request.getMappingData().context;
    if (context != null && !context.getServletContext()
            .getEffectiveSessionTrackingModes().contains(
                    SessionTrackingMode.COOKIE)) {
        return;
    }

    // Parse session id from cookies
    ServerCookies serverCookies = request.getServerCookies();
    int count = serverCookies.getCookieCount();
    if (count <= 0) {
        return;
    }

    String sessionCookieName = SessionConfig.getSessionCookieName(context);

    for (int i = 0; i < count; i++) {
        ServerCookie scookie = serverCookies.getCookie(i);
        if (scookie.getName().equals(sessionCookieName)) {
            // Override anything requested in the URL
            if (!request.isRequestedSessionIdFromCookie()) {
                // Accept only the first session id cookie
                convertMB(scookie.getValue());
                request.setRequestedSessionId
                        (scookie.getValue().toString());
                request.setRequestedSessionCookie(true);
                request.setRequestedSessionURL(false);
                if (log.isDebugEnabled()) {
                    log.debug(" Requested cookie session id is " +
                            request.getRequestedSessionId());
                }
            } else {
                if (!request.isRequestedSessionIdValid()) {
                    // Replace the session id until one is valid
                    convertMB(scookie.getValue());
                    request.setRequestedSessionId
                            (scookie.getValue().toString());
                }
            }
        }
    }
}

๋‚ด๋ถ€์—์„œ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์ฟ ํ‚ค๋ฅผ ์ฐพ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ, ์ฐพ์œผ๋ฉด URL์—์„œ ์–ป์€ ๊ฐ’์€ false๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.

โญ์•„๋ฌดํŠผ, ์ด๋Ÿฌํ•œ ๊ณผ์ • ๋•Œ๋ฌธ์— jessionId ๋Œ€์‹  ์ฟ ํ‚ค์— ์žˆ๋Š” ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด sessionTrackingMode๋ฅผ Cookie๋กœ ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฒƒ.

 

๐Ÿšฉ ๋‚˜์ค‘์— ๊ฐ•์˜ ๋ณด๋ฉด์„œ ์•Œ๊ฒŒ ๋œ ๊ฑด๋ฐ, ๊ตณ์ด ์ด๋ ‡๊ฒŒ ๋นˆ ๋“ฑ๋ก์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„๋„... 

application.properties์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค...! ใ…Žใ…Ž

server.servlet.session.tracking-modes=cookie

 

 

โœ” ์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” ์„ธ์…˜ ์‚ฌ์šฉํ•˜๊ธฐ

- ์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” @SessionAttribute๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ธ์…˜์„ ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

[LHomeController.java]

@GetMapping("/")
public String home(
        @SessionAttribute(name = "loginMember", required = false) LMember loginMember,
        Model model) {

    if (loginMember == null) {
        return "login/home";
    }
    model.addAttribute("member", loginMember);
    return "login/loginHome";
}

- @SessionAttribute๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด name์ด loginMember์ธ ์„ธ์…˜์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

- โญ ์ด๋•Œ๋Š” ์„ธ์…˜์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ๋‹จ์ˆœํžˆ ์กฐํšŒ ๊ธฐ๋Šฅ๋งŒ ์ œ๊ณตํ•œ๋‹ค.

 

 

โœ” ์„ธ์…˜์ด ์ œ๊ณตํ•˜๋Š” ์ •๋ณด

 

session.getId() JSessionID ๊ฐ’
session.getMaxInactiveInterval() ์„ธ์…˜์˜ ์œ ํšจ ์‹œ๊ฐ„, ์ดˆ ๋‹จ์œ„
new Date(session.getCreationTime()) ์„ธ์…˜์˜ ์ƒ์„ฑ ์ผ์ž
new Date(session.getLastAccessedTime()) ์„ธ์…˜๊ณผ ์—ฐ๊ฒฐ๋œ ์‚ฌ์šฉ์ž๊ฐ€ ์ตœ๊ทผ ์„œ๋ฒ„์— ์ ‘์†ํ•œ ์‹œ๊ฐ„
- ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ JsessionID๋ฅผ ์š”์ฒญํ•œ ๊ฒฝ์šฐ ๊ฐฑ์‹ 
session.isNew() ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์„ธ์…˜์ธ์ง€, ์ด๋ฏธ ์ƒ์„ฑ๋˜๊ณ  ์กฐํšŒ๋œ ์„ธ์…˜์ธ์ง€ ์—ฌ๋ถ€

 

- ์ถ”๊ฐ€์ ์œผ๋กœ, ์„ธ์…˜์˜ ์œ ์ง€ ์‹œ๊ฐ„์€ ๋ณดํ†ต LastAccessedTime + alpha์˜ ํ˜•์‹์œผ๋กœ ์ง„ํ–‰ํ•œ๋‹ค.

- ์š”์ฒญ์„ ํ•  ๋•Œ๋งˆ๋‹ค ๊ทธ๋งŒํผ ์œ ์ง€ ์‹œ๊ฐ„์ด ๋” ์ง€์†๋˜๋Š” ๊ฒƒ.

- application.properties๋ฅผ ํ†ตํ•ด์„œ ๋”ฐ๋กœ ์„ค์ •๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

session.setMaxInactiveInterval(1800);

 

- WAS์—์„œ๋Š” LastAccessedTime + alpha ๋งŒํผ์˜ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ๋‚ด๋ถ€์—์„œ ์„ธ์…˜์„ ์ œ๊ฑฐํ•œ๋‹ค. (HttpSession ๊ธฐ์ค€)

 

- ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” ํ•„ํ„ฐ, ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ํ†ตํ•œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ์•Œ์•„๋ณด์ž.

Comments