Thymeleaf 게시판 로그인기능 구현

Yeeun·2025년 5월 2일
0

SpringBoot

목록 보기
35/46

로그인 = 세션 세션에 로그인했다는 정보르 남겨두는 것. 객체가되든 특수한 데이터정보든... 그러면 로그인되었다 인증됨. jsp,서블릿, 부트 다 똑같음.

다만 jsp에선 세션에 저장된 정보를 다 읽어옴. 겟오브젝트해서.. 부트에선 그것보단 주입받는방식으로 끝냄

타임리프에 스프링 시큐리티에서 제공하고있는 기법들
폼 안에 시큐리티 타임리프 라이브러리 ?

1.인덱스페이지 추가 ->로그인하고 겟보드리스트 바로갈수있늬? 위치가 리소스가 아니라 스태틱폴더에 들어감. 그래서 타임리프 어쩌고 안들어감. 템플릿이 아니라 순수한 html이라.

데브툴 설치했는데 서버 자동재구동 안된 이유 => 자바파일이 변경되면 자동재구동임. html은 상관 x 그래서 서버 껐다 켜야함.

로그인은 무조건 호출할때 포스트임.왜냐면 유알엘에 다뜨니까..포스트로 하면 바디에 들어가서 안보이니 .


🔐 Spring Boot 로그인과 세션, 그리고 Thymeleaf에서의 처리 방식

✅ 로그인 = 세션

로그인 처리는 세션(Session)에 인증 정보를 저장하는 것입니다.
이 정보는 객체일 수도 있고, 단순한 값(String 등)일 수도 있어요.
세션에 로그인 정보가 남아있다면, 그 사용자는 **"인증된 상태"**로 간주됩니다.

  • JSP/Servlet: session.getAttribute("user") 같은 방식으로 세션 정보를 직접 꺼내 씁니다.
  • Spring Boot: 주로 @SessionAttribute, @AuthenticationPrincipal, SecurityContextHolder 등으로 주입 받아 사용합니다.

✅ Thymeleaf에서 로그인 처리와 Spring Security

Thymeleaf는 Spring Security와 연동이 잘 되어 있어서, 템플릿에서도 다양한 보안 처리를 할 수 있습니다.
이를 위해 Spring Security용 Thymeleaf 확장 라이브러리를 추가해야 합니다.

<!-- Maven -->
<dependency>
  <groupId>org.thymeleaf.extras</groupId>
  <artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>

📌 이 라이브러리를 적용하면 <sec:authorize> 같은 태그 없이도 다음과 같은 처리 가능:

<!-- 로그인한 사용자 이름 출력 -->
<p th:text="${#authentication.name}">로그인 사용자</p>

<!-- 로그인 여부에 따라 메뉴 표시 -->
<div sec:authorize="isAuthenticated()">로그아웃</div>
<div sec:authorize="isAnonymous()">로그인</div>

✅ index.html은 static 폴더에 위치함

  • src/main/resources/static/index.html에 위치한 파일은 Thymeleaf 템플릿이 아니라 순수 HTML입니다.
  • 이 파일은 Spring이 자동으로 매핑 없이 보여줍니다 (localhost:8080/).
  • 따라서 th:* 속성 같은 Thymeleaf 문법이 작동하지 않습니다.

📝 타임리프 템플릿 처리를 하고 싶다면 resources/templates/ 폴더에 .html 파일을 넣어야 해요.


✅ Devtools 자동 재시작이 안 되는 이유

  • Spring DevTools는 .java 파일이 변경되었을 때만 자동으로 서버를 재시작합니다.
  • .html만 바꿨을 때는 서버가 재시작되지 않음 → 템플릿 캐시가 꺼져 있어야 바로 반영됩니다.

🔧 설정 방법:

# application.properties
spring.thymeleaf.cache=false

그럼에도 불구하고 브라우저 캐시 때문에 반영이 안 될 수 있어요.
이럴 땐 서버를 껐다 켜거나, 강력 새로고침 (Ctrl + F5) 이 필요합니다.


✅ 로그인은 무조건 POST로 처리해야 함

  • GET 방식은 로그인 정보가 URL에 노출되므로 보안상 매우 위험합니다.
  • POST 방식은 데이터가 **요청 바디(body)**에 담기기 때문에 외부 노출이 되지 않아요.
  • 따라서 로그인 처리는 반드시 POST 요청으로만 하도록 설계합니다.
<form method="post" th:action="@{/login}">
  <input type="text" name="username">
  <input type="password" name="password">
  <button type="submit">로그인</button>
</form>


<!DOCTYPE html>
<html>
 <head>
 <title>메인페이지</title>
 <meta http-equiv="Content-Type"
 content="text/html; charset=UTF-8">
 </head>
 <body>
 <br>
 <h3 align="center">게시판프로그램입니다.</h3>
 <hr><hr>
 <p align="center"><a href="getBoardList">글목록바로가기</a></p>
 <p align="center"><a href="login">로그인</a></p><br>
 </body>
 </html>

✅ 수정 및 주석 정리된 LoginController 설명

package ruby.paper.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import ruby.paper.domain.Member;
import ruby.paper.service.MemberService;

@SessionAttributes("member") // 로그인 정보를 세션에 저장
@Controller
public class LoginController {

    @Autowired
    private MemberService memberService;

    // 로그인 페이지 요청 (login.html 렌더링)
    @GetMapping("/login")
    public void loginView() {
        // 뷰 이름이 "login" (templates/login.html)
    }

    // 로그인 처리 요청
    @PostMapping("/login")
    public String login(Member member, Model model) {
        Member findMember = memberService.getMember(member);

        // 회원 정보가 존재하고 비밀번호가 일치하면
        if (findMember != null && findMember.getPassword().equals(member.getPassword())) {
            model.addAttribute("member", findMember); // 세션에 저장됨
            return "redirect:getBoardList"; 
            // 포워드가 아닌 리다이렉트로 이동해야 POST 처리 후 GET 요청이 가능함
            // 만약 포워드를 쓰려면 getBoardList()에 @RequestMapping(value = "/getBoardList", method = {GET, POST})로 명시해줘야 함
        } else {
            return "redirect:login"; // 로그인 실패 → 다시 로그인 페이지로
        }
    }
}

🔍 간단 요약: 세션과 리다이렉트, 포워드 차이

  • @SessionAttributes("member"): 로그인 정보를 세션에 저장함 (model.addAttribute 시 자동 세션 저장).
  • redirect:: 새로운 요청을 클라이언트에게 유도함 → URL이 바뀌고, 메서드(GET/POST)도 새롭게 적용됨.
  • forward:: 서버 내부에서 페이지 이동 → POST 방식 그대로 전달되므로, GET으로 작성된 페이지와 충돌할 수 있음.

0개의 댓글