1. 프로젝트 구조설정
src/main/java/com/example/loginapp/
│
├── config/ # Spring Security 설정
├── controller/ # 프레젠테이션 계층
├── service/ # 서비스 계층
├── repository/ # 저장소 계층
└── domain/ # 도메인 계층
2. 도메인 계층 설정
src/main/java/com/example/loginapp/domain/User.java
package com.example.loginapp.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
@Entity
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String role;
}
3. 저장소 계층 설정
src/main/java/com/example/loginapp/repository/UserRepository.java
package com.example.loginapp.repository;
import com.example.loginapp.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
4. 서비스 계층 설정
src/main/java/com/example/loginapp/service/UserService.java
package com.example.loginapp.service;
import com.example.loginapp.domain.User;
import com.example.loginapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
public Optional<User> findByUsername(String username) {
return userRepository.findByUsername(username);
}
public User save(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
}
5. Spring Security 설정
src/main/java/com/example/loginapp/config/SecurityConfig.java
package com.example.loginapp.config;
import com.example.loginapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(username -> userService.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found")))
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/", true)
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
6. 프레젠테이션 계층 설정
src/main/java/com/example/loginapp/controller/AuthController.java
package com.example.loginapp.controller;
import com.example.loginapp.domain.User;
import com.example.loginapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
private UserService userService;
@PostMapping("/register")
public ResponseEntity<String> register(@RequestBody User user) {
userService.save(user);
return ResponseEntity.ok("User registered successfully");
}
@GetMapping("/login")
public ResponseEntity<String> login() {
return ResponseEntity.ok("Login page");
}
}
7. 데이터베이스 설정 (H2 예제)
src/main/resources/application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
8. 실행 및 테스트
프로젝트를 실행하고 브라우저 또는 Postman과 같은 도구를 사용하여 로그인 및 회원가입 API를 테스트할 수 있습니다.
회원가입: POST /auth/register 엔드포인트에 username, password, role을 포함한 JSON 데이터를 전송합니다.
로그인: Spring Security의 기본 로그인 폼을 사용하거나 직접 만든 /auth/login 엔드포인트로 로그인할 수 있습니다.
이렇게 설정하면 Spring Boot 기반의 레이어드 아키텍처로 로그인 API를 구현한 기본적인 프로젝트가 완성됩니다. 필요에 따라 추가적인 기능과 보안 설정을 확장해 나갈 수 있습니다.
효율적인 로그인 프로세스 (1) | 2024.10.25 |
---|---|
SPRING 레이어드 아키텍처 (1) | 2024.10.23 |
댓글 영역