본 강좌에서는 스프링 부트를 이용한 백엔드 개발을 진행하면서 주로 스프링 시큐리티를 통한 로그인/로그아웃 기능과 회원 가입 기능을 구현하는 방법에 대해 다루겠습니다. 또한, 로그아웃 뷰 추가 방법도 구체적으로 설명할 것입니다. 이 강좌는 기본적인 스프링 부트 프로젝트부터 시작하여, 점진적으로 필요한 기능을 추가해나가는 형태로 진행됩니다.
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를 통해 웹 프론트엔드와의 통신, 클라우드 배포, 테스트 및 배포 자동화 등의 고급 주제에 대해서도 학습해보시기를 권장합니다.
여러분의 개발 여정에 도움이 되었길 바라며, 질문이나 더 궁금한 사항이 있으시다면 댓글로 남겨주세요. 감사합니다!