์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋กœ ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

์ง€๋‚œ ๋ฒˆ์— ์ด์–ด ์ด๋ฒˆ์—” ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ์ด๋‹ค.

ํšŒ์›๊ฐ€์ž…

ํšŒ์›๊ฐ€์ž…์˜ ์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๊ถŒํ•œ์ด ์—†๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญ์„ ํ•  ๊ฒฝ์šฐ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋ฅผ ๋„์›Œ์•ผ ํ•œ๋‹ค. ์ด๋•Œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์— ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๋งํฌ๋ฅผ ๊ฑธ์–ด๋‘”๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ์›๊ฐ€์ž… ๋งํฌ๋กœ ์ ‘์†ํ•˜์—ฌ ํšŒ์›๊ฐ€์ž… ํผ์„ ์ž‘์„ฑํ•œ ๋’ค ์„œ๋ฒ„์— ์ œ์ถœํ•œ๋‹ค. ์„œ๋ฒ„๋Š” ํšŒ์›๊ฐ€์ž… ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•œ ๋’ค ๋‹ค์‹œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜์—ฌ ๋กœ๊ทธ์ธ ํ›„ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ์œ ๋„ํ•œ๋‹ค.

ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

๊ฐ„๋‹จํ•˜๊ฒŒ ๋ธŒ๋ผ์šฐ์ €์— ๋„์šธ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. src/main/resources/templates ์•„๋ž˜์— joinForm.html ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€</title>
</head>
<body>
	<h1>ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€</h1>
	<hr/>
	<form action="/join" method="POST">
		<input type="text" name="username" placeholder="Username"/> <br/>
		<input type="password" name="password" placeholder="Password"/> <br/>
		<input type="email" name="email" placeholder="Email"/> <br/>
		<button>ํ™•์ธ</button>
	</form>
</body>
</html>

์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ ๋ฐ›๊ธฐ

์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ๋ฐ›๋Š”๋‹ค.

Java
/**
 * ์ปจํŠธ๋กค๋Ÿฌ
 */

@Controller
public class IndexController {
    
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private BCryptPasswordEncoder bCryptPasswordEncoder;

    // ํšŒ์› ๊ฐ€์ž… ํผ ํŽ˜์ด์ง€ ๋ฐ˜ํ™˜
	@GetMapping("/joinForm")
	public String joinForm() {
		return "joinForm";
	}
	
    // ํšŒ์› ๊ฐ€์ž… ํผ ํŽ˜์ด์ง€์—์„œ ํ™•์ธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๋กœ์ง ์ฒ˜๋ฆฌ
	@PostMapping("/join")
	public String join(User user) {
		System.out.println(user);
		
		user.setRole("ROLE_USER");
		String rawPassword = user.getPassword();
		String encPassword = bCryptPasswordEncoder.encode(rawPassword);
		user.setPassword(encPassword);
		
		userRepository.save(user);
		return "redirect:/loginForm";
	}
}
  • /joinForm์œผ๋กœ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ๋‹ค. ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์•ž์„œ ๋งŒ๋“ค์–ด๋‘” joinForm.html ํŒŒ์ผ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ /joinForm์—์„œ ๊ฐ’์„ ์ž…๋ ฅํ•˜๊ณ  ์ œ์ถœํ•˜๋ฉด ์ปจํŠธ๋กค๋Ÿฌ์˜ /join ์œผ๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜จ๋‹ค. ๊ณ ๋งˆ์šด JPA ๋•๋ถ„์— User ํƒ€์ž…์˜ ๊ฐ์ฒด๋กœ ๊ฐ’์„ ๋ฐ›๋Š”๋‹ค.
  • ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ธ์ฝ”๋”ฉํ•˜์—ฌ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด BCryptPasswordEncoder ๊ฐ์ฒด์˜ encode() ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•œ๋‹ค.
  • DB์— ์ €์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ ์—‘์„ธ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด JPA UserRepository ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ save() ํ•œ๋‹ค.
  • ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํšŒ์›๊ฐ€์ž… ์ ˆ์ฐจ๊ฐ€ ๋๋‚˜๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜์—ฌ ๋กœ๊ทธ์ธ ํ›„ ์‚ฌ์šฉ์„ ์œ ๋„ํ•œ๋‹ค.

SecurityConfig์— ์ธ์ฝ”๋”ฉ์„ ์œ„ํ•œ ์˜์กด์„ฑ ์ถ”๊ฐ€

์œ„์™€ ๊ฐ™์ด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ธ์ฝ”๋”ฉ ํ•˜๊ธฐ์œ„ํ•ด BCryptPasswordEncoder ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. SecurityConfig ํด๋ž˜์Šค์— ์ธ์ฝ”๋”ฉ์„ ์œ„ํ•œ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

/**
 * ์‹œํ๋ฆฌํ‹ฐ ์„ค์ •
 */

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

	// ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋กœ ๋ฆฌํ„ด๋˜๋Š” ์˜ค๋ธŒ์ ํŠธ๋ฅผ IoC๋กœ ๋“ฑ๋ก
	@Bean
	public BCryptPasswordEncoder encodePwd() {
		return new BCryptPasswordEncoder();
	}

    ...

}

๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™” ์„ฑ๊ณต~

๋กœ๊ทธ์ธ

๋Œ€๋ง์˜ ๋กœ๊ทธ์ธ! ์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ํšŒ์›๊ฐ€์ž… ํ›„ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋˜์–ด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ํ˜น์€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ ‘์†ํ•œ ๊ฒฝ์šฐ, ๋‚˜์•„๊ฐ€ ๊ถŒํ•œ์ด ์—†๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•  ๊ฒฝ์šฐ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๊ฐ€ ๋„์›Œ์ง„๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ํผ์„ ์ž‘์„ฑํ•œ ๋’ค ์ œ์ถœํ•˜๋ฉด ์„œ๋ฒ„๋Š” ๋กœ๊ทธ์ธ ๊ฒ€์ฆ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•œ ๋’ค ์ธ๋ฑ์Šค ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ์•„๋‹ˆ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์›๋ž˜ ์ ‘๊ทผํ•˜๊ณ ์ž ํ–ˆ๋˜ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค.

๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

๊ฐ„๋‹จํ•˜๊ฒŒ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. src/main/resources/templates ์•„๋ž˜์— loginForm.html ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>๋กœ๊ทธ์ธ ํŽ˜์ด์ง€</title>
</head>
<body>
	<h1>๋กœ๊ธด ํŽ˜์ด์ง€</h1>
	<hr/>
	<form action="/login" method="POST">
		<input type="text" name="username" placeholder="Username"/> <br/>
		<input type="password" name="password" placeholder="Password"/> <br/>
		<button>ํ™•์ธ</button>
	</form>
	<a href="/joinForm">ํšŒ์›๊ฐ€์ž… ํ•˜๋Ÿฌ ๊ฐ€๊ธฐ</a>
</body>
</html>

์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ ๋ฐ›๊ธฐ

์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ๋ฐ›๋Š”๋‹ค.

Java
/**
 * ์ปจํŠธ๋กค๋Ÿฌ
 */

@Controller
public class IndexController {
    
	@GetMapping("/loginForm")
	public String loginForm() {
		return "loginForm";
	}
}
  • ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ๋กœ์ง์€ SecurityConfig ํด๋ž˜์Šค์˜ configure() ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ /login ์š”์ฒญ์— ๋Œ€ํ•œ @PostMapping์€ ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋œ๋‹ค!(๋‹จ, spring security ์ดˆ๊ธฐ ๊ฐ’์— ์˜ํ•˜๋ฉด ์ปจํŠธ๋กค๋Ÿฌ์˜ /login ์š”์ฒญ์€ ์ž์ฒด ์ œ์ž‘๋œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์—ฐ๊ฒฐ๋œ๋‹ค)

์‹œํ๋ฆฌํ‹ฐ ์„ค์ •์—์„œ ๋กœ๊ทธ์ธ ์š”์ฒญ ์ฒ˜๋ฆฌ

SecurityConfig ํด๋ž˜์Šค์—์„œ ์ฒด์ด๋‹์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ ํผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.

/**
 * ์‹œํ๋ฆฌํ‹ฐ ์„ค์ •
 */

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable();
		http.authorizeRequests()
			.antMatchers("/user/**").authenticated()    // ์ธ์ฆ๋งŒ ๋˜๋ฉด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ฃผ์†Œ
			.antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')")
			.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
			.anyRequest().permitAll()
			.and()
			.formLogin()
			.loginPage("/loginForm")
			.loginProcessingUrl("/login")	  // /login ์ฃผ์†Œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋‚š์•„์ฑ„ ๋Œ€์‹  ๋กœ๊ทธ์ธ ์ง„ํ–‰ -> Controller์— '/login' ๋งŒ๋“ค์ง€ ์•Š์•„๋„ ๋จ
			.defaultSuccessUrl("/");
	}
}
  • .formLogin() : ๋กœ๊ทธ์ธ ํผ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ /login ์š”์ฒญ์„ ๋งŒ๋“ค์–ด์คŒ
  • .loginPage("/loginForm") : ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ •์˜ํ•œ ๋กœ๊ทธ์ธ ํผ ์š”์ฒญ ํŽ˜์ด์ง€ ์„ค์ •
  • .loginProcessingUrl("/login") : ๋กœ๊ทธ์ธ ํผ ๋ฐ์ดํ„ฐ๋ฅผ /login ์š”์ฒญ์œผ๋กœ ๋„˜๊น€
  • .defaultSuccessUrl("/"); : ๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋  ๊ฒฝ๋กœ

๋กœ๊ทธ์ธ ๊ฒ€์ฆ ๋กœ์ง ๊ตฌํ˜„ํ•˜๊ธฐ

๋กœ๊ทธ์ธ ํผ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ฆํ•  ์ฐจ๋ก€๋‹ค.

Spring Security๋Š” /login ์ฃผ์†Œ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์ด๋ฅผ ๋‚š์•„์ฑ„ ๋กœ๊ทธ์ธ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋˜๋ฉด Security Session์„ ์ƒ์„ฑํ•œ๋‹ค.(Security ContextHolder ๋ผ๋Š” ํ‚ค๊ฐ’์— ์„ธ์…˜ ์ •๋ณด๋ฅผ ์ €์žฅ)

์ด๋•Œ Spring Security๋Š” Security Session์— Authentication ๋ผ๋Š” ํŠน์ •ํ•œ ๊ฐ์ฒด ํƒ€์ž…์œผ๋กœ ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค.

๋™์‹œ์— Authentication ๊ฐ์ฒด๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ณ  ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ํŠน์ • ๊ฐ์ฒด ํƒ€์ž…์ด ์žˆ๋Š”๋ฐ ์ด๋ฅผ UserDetails๋ผ๊ณ  ํ•œ๋‹ค.

Security Session -> Authentication ํƒ€์ž… ๊ฐ์ฒด ๊ฐ€์ง -> UserDetails ํƒ€์ž… ๊ฐ์ฒด ๊ฐ€์ง

๋”ฐ๋ผ์„œ auth ํŒจํ‚ค์ง€ ์•ˆ์— PrincipalDetails ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•œ๋’ค ์ด ํด๋ž˜์Šค๋Š” UserDetails ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•œ๋‹ค.

Java
/**
 * ๋กœ๊ทธ์ธ ๋ฐ˜ํ™˜ ์„ค์ •
 */

public class PrincipalDetails implements UserDetails{

	private User user;
	
    // ์ƒ์„ฑ์ž
	public PrincipalDetails(User user) {
		this.user = user;
	}
	
	// User์˜ ๊ถŒํ•œ์„ ๋ฆฌํ„ด
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		Collection<GrantedAuthority> collect = new ArrayList<GrantedAuthority>();
		collect.add(new GrantedAuthority() {
			
			@Override
			public String getAuthority() {
				return user.getRole();
			}
		});
		return collect;
	}

    // User์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ฆฌํ„ด
	@Override
	public String getPassword() {
		return user.getPassword();
	}

    // User์˜ ์œ ์ €๋„ค์ž„์„ ๋ฆฌํ„ด
	@Override
	public String getUsername() {
		return user.getUsername();
	}

    // ๊ณ„์ • ์ •๋ณด ๋งŒ๋ฃŒ ์—ฌ๋ถ€
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

    // ๊ณ„์ • ์ž ๊ธˆ ์—ฌ๋ถ€
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

    // ๊ณ„์ • ๋น„๋ฐ€๋ฒˆํ˜ธ ๋“ฑ ๋งŒ๋ฃŒ ์—ฌ๋ถ€
	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

    // ํœด๋ฉด ์‚ฌ์šฉ์ž ์—ฌ๋ถ€
	@Override
	public boolean isEnabled() {
		// ๋งŒ์•ฝ 1๋…„๊ฐ„ ๋กœ๊ธด ์•ˆํ•ด์„œ ํœด๋ฉด ๊ณ„์ •์œผ๋กœ ๋ณ€ํ™˜๋  ๋•Œ ์ด ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ ๋น„ํ™œ์„ฑํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ
		// User ์˜ค๋ธŒ์ ํŠธ ํƒ€์ž…์— loginDate ๋ผ๋Š” ํ•„๋“œ ์ถ”๊ฐ€ํ•ด์„œ ๋กœ๊ธดํ• ๋•Œ๋งˆ๋‹ค ๋‚ ์งœ ์ €์žฅํ•ด๋‘ 
		// ํ˜„์žฌ๋‚ ์งœ - ๋กœ๊ธด๋‚ ์งœ > 1๋…„ -> return false ๋กœ ๋ถ„๊ธฐํ•ด์ฃผ๋ฉด ๋จ
		return true;
	}

}

์œ„์™€ ๊ฐ™์ด ๋กœ๊ทธ์ธ ์‹œ ๋ฐ˜ํ™˜ํ•  ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ–ˆ๋‹ค๋ฉด ์‹ค์ œ๋กœ ๋กœ๊ทธ์ธ ์„œ๋น„์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ฐจ๋ก€๋‹ค.

auth ํŒจํ‚ค์ง€ ์•ˆ์— PrincipalDetailsService ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•œ๋’ค ์ด ํด๋ž˜์Šค๋Š” UserDetailsService ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•œ๋‹ค. ๋˜ํ•œ @Service ์–ด๋…ธํ…Œ์ด์…˜์„ ์žŠ์ง€ ๋ง์ž.

/login ์š”์ฒญ ์‹œ ์ž๋™์œผ๋กœ UserDetailService ํƒ€์ž…์œผ๋กœ IoC ๋˜์–ด์žˆ๋Š” loadUserByUsername() ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

Java
/**
 * ๋กœ๊ทธ์ธ ๋กœ์ง ์„œ๋น„์Šค
 */

@Service
public class PrincipalDetailsService implements UserDetailsService {

	@Autowired
	private UserRepository userRepository;
	
	// (Security Session ๋‚ด๋ถ€์— (Authentication ๋‚ด๋ถ€์— (UserDatails)))
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		User userEntity = userRepository.findByUsername(username);
		if (userEntity != null) {
			return new PrincipalDetails(userEntity);
		}
		return null;
	}

}
  • DB์˜ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•ด JPA UserRepository ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ Query Method ๋ฐฉ์‹์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ๋ฐ˜ํ™˜ ํƒ€์ž…์€ PrincipalDetails ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค.

์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ๊นŒ์ง€ ์ž˜ ๋œ๋‹ค. ใ…Žใ…Ž



Reference

์ธํ”„๋Ÿฐ ์ตœ์ฃผํ˜ธ๋‹˜ ์Šคํ”„๋ง๋ถ€ํŠธ ์‹œํ๋ฆฌํ‹ฐ & JWT ๊ฐ•์˜ - ์„น์…˜ 0. ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๊ธฐ๋ณธ