본 강좌에서는 스프링 부트를 이용한 백엔드 개발을 진행하면서 주로 스프링 시큐리티를 통한 로그인/로그아웃 기능과 회원 가입 기능을 구현하는 방법에 대해 다루겠습니다. 또한, 로그아웃 뷰 추가 방법도 구체적으로 설명할 것입니다. 이 강좌는 기본적인 스프링 부트 프로젝트부터 시작하여, 점진적으로 필요한 기능을 추가해나가는 형태로 진행됩니다.
1. 스프링 부트 프로젝트 설정
스프링 부트는 자바 기반의 웹 애플리케이션을 빠르게 개발할 수 있도록 돕는 프레임워크입니다. 본 강좌에서는 최신 버전의 스프링 부트를 사용하여 프로젝트를 설정할 것입니다. 다음은 스프링 부트 프로젝트를 설정하는 단계입니다.
1. Spring Initializr를 사용하여 기본 프로젝트 생성
- https://start.spring.io/로 이동합니다.
- Project: Maven Project
- Language: Java
- Spring Boot: 최신 버전 선택
- Project Metadata 설정:
- Group: com.example
- Artifact: demo
- Dependencies 추가:
- Spring Web
- Spring Security
- Spring Data JPA
- H2 Database (내장 데이터베이스)
- Generate 버튼 클릭하여 ZIP 파일 다운로드 후 압축 해제
1.1. IDE에서 프로젝트 열기
다운로드 받은 프로젝트를 IDE에서 열어줍니다. IntelliJ IDEA 혹은 Eclipse와 같은 IDE를 사용할 수 있습니다. 각 IDE에서 Maven을 통해 의존성 라이브러리를 자동으로 다운로드합니다.
2. 도메인 모델 설계
회원 가입과 로그인을 위해 사용자 정보를 저장할 도메인 모델을 설계합니다. User라는 클래스를 만들고, JPA를 활용하여 데이터베이스에 매핑합니다.
package com.example.demo.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String email;
// Getter and Setter
}
2.1. User Repository 생성
사용자 데이터를 조작하기 위해 UserRepository 인터페이스를 생성합니다. JPA의 CrudRepository를 확장하여 기본적인 CRUD 기능을 사용할 수 있도록 합니다.
package com.example.demo.repository;
import com.example.demo.model.User;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository {
User findByUsername(String username);
}
3. 스프링 시큐리티 설정
로그인 및 회원 가입 기능을 구현하기 위해 스프링 시큐리티를 설정합니다. 스프링 시큐리티는 애플리케이션의 보안 성능을 높여주는 강력한 프레임워크입니다.
3.1. Security Configuration 클래스
스프링 시큐리티의 설정을 위한 클래스를 생성합니다. SecurityConfig 클래스를 작성하여 인증 및 인가에 대한 기본적인 설정을 합니다.
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// UserDetailsService와 PasswordEncoder 설정
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/register").permitAll() // 회원 가입 페이지는 모두 허용
.anyRequest().authenticated() // 나머지 요청은 인증 필요
.and()
.formLogin()
.loginPage("/login") // 커스터마이징된 로그인 페이지
.permitAll()
.and()
.logout()
.permitAll(); // 로그아웃을 허용
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
4. 회원 가입 기능 구현
회원 가입 기능을 위한 REST Controller와 회원 가입 뷰를 구현합니다. 사용자에게 입력받은 정보를 이용해 User 객체를 생성하고, 패스워드는 안전하게 해시 처리하여 저장해야 합니다.
4.1. User Controller 클래스 생성
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
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.RequestMapping;
@Controller
@RequestMapping("/register")
public class UserController {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@GetMapping
public String showRegistrationForm(Model model) {
model.addAttribute("user", new User());
return "register";
}
@PostMapping
public String registerUser(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword())); // 패스워드 해싱
userRepository.save(user); // 사용자 저장
return "redirect:/login"; // 회원 가입 후 로그인 페이지로 리디렉션
}
}
4.2. 회원 가입 뷰
회원 가입을 위한 Thymeleaf 뷰를 생성합니다. 이는 HTML 파일로 존재하며, 사용자가 정보를 입력하고 제출할 수 있는 폼을 제공합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>회원 가입</title>
</head>
<body>
<h1>회원 가입</h1>
<form action="/register" method="post">
<label for="username">사용자 이름</label>
<input type="text" id="username" name="username" required>
<label for="password">패스워드</label>
<input type="password" id="password" name="password" required>
<label for="email">이메일</label>
<input type="email" id="email" name="email" required>
<button type="submit">가입하기</button>
</form>
</body>
</html>
5. 로그인 기능 구현
로그인 기능을 위해 추가적인 컨트롤러와 뷰를 설정합니다. 사용자가 로그인할 때 입력한 정보를 바탕으로 인증을 진행합니다.
5.1. 로그인 페이지 설정
로그인 페이지를 위한 HTML 파일을 생성합니다. 사용자 이름과 패스워드를 입력받는 필드가 포함되어야 합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
<h1>로그인</h1>
<form action="/login" method="post">
<label for="username">사용자 이름</label>
<input type="text" id="username" name="username" required>
<label for="password">패스워드</label>
<input type="password" id="password" name="password" required>
<button type="submit">로그인</button>
</form>
<a href="/register">회원 가입하러 가기</a>
</body>
</html>
6. 로그아웃 구현 및 뷰 추가
로그아웃 기능을 추가합니다. 로그아웃 후에는 메인 화면으로 리디렉션되도록 설정합니다.
6.1. 로그아웃 기능 설정
이미 설정된 HttpSecurity를 통해 로그아웃 기능은 쉽게 구현할 수 있습니다. 사용자가 로그아웃을 요청하면, 인증 세션이 무효화되며 리디렉션됩니다.
6.2. 로그아웃 후 리디렉션 페이지 생성
로그아웃 후 사용자가 볼 수 있는 페이지를 만들어줍니다. 여기서 적절한 메시지를 제공할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>로그아웃</title>
</head>
<body>
<h1>로그아웃 되었습니다.</h1>
<p>다시 로그인하려면 아래 버튼을 클릭하세요.</p>
<a href="/login">로그인 페이지로 이동</a>
</body>
</html>
7. 결론 및 다음 단계
이번 강좌에서는 스프링 부트를 활용하여 백엔드 개발을 진행하며 스프링 시큐리티로 로그인 및 로그아웃 기능, 회원 가입 기능을 구현하였습니다. 이러한 기초적인 기능들을 익히고 나면, 추가적으로 JWT(JSON Web Token) 기반의 인증, OAuth2를 이용한 소셜 로그인, 비밀번호 재설정 기능 등 보다 확장된 기능을 구현하는 것도 가능합니다.
또한, 이 강좌를 바탕으로 RESTful API를 통해 웹 프론트엔드와의 통신, 클라우드 배포, 테스트 및 배포 자동화 등의 고급 주제에 대해서도 학습해보시기를 권장합니다.
여러분의 개발 여정에 도움이 되었길 바라며, 질문이나 더 궁금한 사항이 있으시다면 댓글로 남겨주세요. 감사합니다!