์ข์! ๐
์ง๊ธ๋ถํฐ Spring Boot + Spring Security๋ก ์๋ 4๊ฐ์ง ํต์ฌ ๊ธฐ๋ฅ์ ๋จ๊ณ๋ณ๋ก ์ ๋ฆฌํด์ค๊ฒ:
| ๊ธฐ๋ฅ ๋ฒํธ | ๊ตฌํ ํญ๋ชฉ |
|---|---|
| 1๏ธโฃ | DB ๊ธฐ๋ฐ ํ์๊ฐ์ & ๋ก๊ทธ์ธ |
| 2๏ธโฃ | Redis ์ธ์ ์ ์ฅ ๋ฐฉ์ ์ ์ฉ |
| 3๏ธโฃ | ๋ก๊ทธ์ธ ์คํจ ๋ฉ์์ง ์ฒ๋ฆฌ |
| 4๏ธโฃ | ๋ก๊ทธ์ธ ์ํ ํ์ธ (์ธ์ ์์ ์ฌ์ฉ์ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ) |
src/
โโโ main/
โโโ java/
โ โโโ com.example.securitydemo/
โ โโโ config/ โ Security ์ค์
โ โโโ controller/ โ ๋ก๊ทธ์ธ/ํ ์ปจํธ๋กค๋ฌ
โ โโโ entity/ โ User ์ํฐํฐ
โ โโโ repository/ โ JPA Repository
โ โโโ service/ โ UserDetailsService ๊ตฌํ
โ โโโ SecurityDemoApplication.java
โโโ resources/
โโโ templates/
โ โโโ login.html
โ โโโ home.html
โโโ application.yml
@Entity
public class User {
@Id
private String username;
private String password;
private String role;
}
public interface UserRepository extends JpaRepository<User, String> {
}
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) {
User user = userRepository.findById(username).orElseThrow();
return org.springframework.security.core.userdetails.User.builder()
.username(user.getUsername())
.password(user.getPassword()) // ์ํธํ ํ์
.roles(user.getRole())
.build();
}
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/register", "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home", true)
.failureUrl("/login?error=true")
.and()
.logout()
.logoutSuccessUrl("/login?logout");
}
@PostMapping("/register")
public String register(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
userRepository.save(user);
return "redirect:/login";
}
implementation 'org.springframework.session:spring-session-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
spring:
redis:
host: localhost
port: 6379
session:
store-type: redis
timeout: 30m
โ Redis ์๋ฒ๋ ๋ฐ๋ก ์ผ์ค์ผ ํจ (
redis-server๋ช ๋ น์ด ๋๋ Docker)
<div th:if="${param.error}">
<p style="color:red;">๋ก๊ทธ์ธ ์คํจ! ์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํ์ธ์.</p>
</div>
/login?error=trueโparam.error๋ก ํ๋ฉด์ ํ์ ๊ฐ๋ฅ
@GetMapping("/home")
public String home(Model model, Authentication authentication) {
String username = authentication.getName(); // ์ธ์
์ ์ ๋ช
model.addAttribute("username", username);
return "home";
}
| ๊ธฐ๋ฅ | ๊ตฌํ ๋ฐฉ์ |
|---|---|
| โ DB ๋ก๊ทธ์ธ | UserDetailsService + JPA |
| โ ์ธ์ ์ ์ฅ์ | Redis ์ ์ฉ + spring.session.store-type: redis |
| โ ์คํจ ๋ฉ์์ง | /login?error=true + Thymeleaf ์กฐ๊ฑด |
| โ ๋ก๊ทธ์ธ ์ํ ํ์ธ | Authentication.getName() ๋๋ Principal.getName() |
ํ์ํ๋ค๋ฉด:
๊น์ง ๊ฐ๋ฅํด!
ํน์ ์ง๊ธ ์งํ ์ค์ธ ํ๋ก์ ํธ์ ๋ง์ถฐ ์ปค์คํฐ๋ง์ด์งํด์ค๊น? ๐ค