빙응의 공부 블로그
[Spring]스프링 시큐리티 - 간단한 실습 본문

📝스프링 시큐리티 실습
목표 : 계정 역할 없이 로그인 창 구현
- 회원 가입을 위한 Validation도 포함
생성 파일
- Config
- SecurityConfig
- controller
- LoginController
- domain
- DTO
- JoinDTO
- Member
- DTO
- repository
- MemberRepository
- Service
- LoginService
- MemberService
- View
- join.html
- login.html
- main.html
사용 의존성
- Spring Security
- Lombok
- Validation
- Thymeleaf
- MySQL
- Jpa
🚩도메인 및 DTO 구성
Member
@Entity
@Getter
@Setter
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String userName;
private String password;
}
간단한 구성을 위해 아이디와 비번만 설정하였다.
JoinDTO
@Getter
@Setter
public class JoinDTO {
@NotBlank(message = "이름은 필수 입력 값입니다.")
@Length(min = 3,max = 16,message = "아이디를 8자 이상, 16자 이하로 입력해주세요")
private String userName;
@NotEmpty(message = "비밀번호는 필수 입력 값입니다.")
@Length(min = 8,max = 16,message = "비밀번호는 8자 이상, 16자 이하로 입력해주세요")
private String password;
}
회원가입 폼에서 사용할 DTO이며, Validation을 위한 제약조건도 설정하였다.
MemberRepository
@Repository
public interface MemberRepository extends JpaRepository<Member,Long> {
Member findByUserName(String userName);
}
JPA 접근을 위해 리포지토리 설정을 해주었다.
🚩Spring Security 설정
밑에서 보는 것처럼 시큐리티 설정은 혼자 해보면서 하나하나 이해하는 것이 좋다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); //보안을 위한 비밀번호 엔코더
}
@Bean
public SecurityFilterChain Security(HttpSecurity httpSecurity)throws Exception{
httpSecurity
.authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/login","/","/loginProc","/join","/css/**").permitAll() //해당 위치는 접근 가능
//.requestMatchers("/admin").hasRole("Admin") // 어드민 Role을 가지고 있는 사용자만 접근 가능
.anyRequest().authenticated() // 나머지 모든 페이지는 인증 검사
);
httpSecurity
.formLogin(login ->
login
.loginPage("/login")//로그인 페이지 설정
.loginProcessingUrl("/loginProc")//시큐리티 로그인 처리 로직 url 지정
.defaultSuccessUrl("/main",true)//로그인 인증 성공 시 이동할 페이지
.usernameParameter("userName")
.passwordParameter("password")
.permitAll()
);
httpSecurity
.csrf((auth)->auth.disable()); //csrf 사용 거부
httpSecurity
.logout(logout -> logout
.logoutUrl("/logout") // 로그아웃 URL 지정
.logoutSuccessUrl("/loginPage") // 로그아웃 성공 시 이동할 URL 지정
.invalidateHttpSession(true) // 세션 무효화
.deleteCookies("JSESSIONID")// 쿠키 삭제
.permitAll());
return httpSecurity.build();
}
}
🚩Service 구현
@RequiredArgsConstructor
@Slf4j
@Transactional(readOnly = true) // 모든 메서드에 읽기 전용 트랜잭션 적용
public class MemberService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
@Transactional // 쓰기 작업에 대한 트랜잭션 적용
public void join(Member member){
member.setPassword(passwordEncoder.encode(member.getPassword()));
memberRepository.save(member);
}
/**
* 회원가입 시 동일한 회원 아이디가 있는지 검사합니다.
* @param userName
* @return
*/
public boolean checkDuplicateUsername(String userName){
Member member = memberRepository.findByUserName(userName);
return member != null;
}
}
간단한 회원가입과 회원가입 시 아이디 중복 검사만 해주었다.
트랜잭션 효율화를 위해 읽기 전용으로 설정해 주었다.
@Transactional(readOnly = true)
🚩Controller
@Controller
@Slf4j
@RequiredArgsConstructor
public class LoginController {
private final MemberService memberService;
@GetMapping("/login")
public String loginPage(){
return "login";
}
@GetMapping("/main")
public String mainPage(Model model){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String userName = authentication.getName();
model.addAttribute("userName", userName);
return "main";
}
@GetMapping("/join")
public String joinPage(Model model){
model.addAttribute("joinDTO", new JoinDTO());
return "join";
}
@PostMapping("/join")
public String joinProc(@Valid @ModelAttribute JoinDTO joinDTO, BindingResult bindingResult){
// 아이디 중복 체크
if(memberService.checkDuplicateUsername(joinDTO.getUserName())) {
bindingResult.reject("userName", "아이디가 중복됩니다.");
}
// 유효성 검사 및 오류 처리
if (bindingResult.hasErrors()) {
log.info("errors={}", bindingResult);
return "join";
}
// 중복 아이디가 없는 경우 회원가입 처리
Member member = new Member();
member.setUserName(joinDTO.getUserName());
member.setPassword(joinDTO.getPassword());
memberService.join(member);
return "redirect:/login"; // 로그인 페이지로 리다이렉트
}
}
회원가입 시 컨트롤러를 이용해 유효성 검사(@Valid)와 아이디 중복 체크를 해주었다.
만약 아이디가 중복되면 글로벌 오류로 등록하여 다시 join 페이지로 돌아가 오류를 표시하였다.



Spring Security로 간단한 실습을 해보았다.
나는 정말 간단한 형태로 권한, 커스텀 정보 인증을 제외하였다.
'Spring > 개인공부_실습' 카테고리의 다른 글
[React + Spring]리액트와 스프링으로 API 받아서 처리하기 (0) | 2024.05.20 |
---|---|
[Spring]Spring - RestTemplate (0) | 2024.05.19 |
[React + Spring]리액트와 스프링 - 연동 (0) | 2024.05.17 |
[Spring]Spring Security + JWT(2) (1) | 2024.04.07 |
[Spring]Spring Security + JWT(1) (1) | 2024.04.07 |