반응형
250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Blazor
- 인프런자바스크립트
- 인프런강의
- 자바스크립트객체리터럴
- c#
- 객체리터럴
- 자바스크립트
- 인터넷프로토콜
- 객체의비교
- EntityFramework
- sort
- 인프런무료강좌
- slice
- 제로초
- 고차함수
- 자바스크립트파라미터
- HTTP
- 이벤트리스너
- 자바스크립트틱택토
- .NET
- 자바스크립트함수
- 비주얼스튜디오
- 자바스크립트recude
- 틱택토구현
- 인프런인강
- 콜백함수
- 인프런강좌
- 코딩
- 인프런
- NPM
Archives
- Today
- Total
샐님은 개발중
#3. 스프링 시큐리티를 활용한 로그인/회원가입 (2) 본문
728x90
반응형
1. 스프링 시큐리티를 이용해서 로그인 구현
- UserDetailsService 인터페이스
- 데이터베이스에서 회원 정보를 가져오는 역할 담당. loadUserByUsername() 메소드 존재, 사용자의 정보와 권한을 갖는 UserDetails 인터페이스 반환
1) 기존에 만들었던 MemberService에 UserDetailsService 를 구현해보자.
(패키지/임포트 정보 생략)
@Service
@Transactional
@RequiredArgsConstructor
public class MemberService implements UserDetailsService {
(중략)
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Member member = memberRepository.findByEmail(email);
if(member == null){
throw new UsernameNotFoundException(email);
}
// user 객체를 반환
return User.builder()
.username(member.getEmail())
.password(member.getPassword())
.roles(member.getRole().toString())
.build();
}
}
2) 스프링 시큐리티 설정 (3.XX 대 버전, 2.xx 대 버전의 내용과 다릅니다.)
package won.shop.config;
import jakarta.servlet.DispatcherType;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
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.WebSecurityCustomizer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import won.shop.Service.MemberService;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
@Autowired
MemberService memberService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable().cors().disable()
.authorizeHttpRequests(request -> request
.dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll()
.requestMatchers("/", "/members/new","/logout","/css/**","/*.ico","/img/**","/layout/**","/item/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(login -> {
try {
login
.loginPage("/members/login") // 로그인 페이지 지정
.defaultSuccessUrl("/") // 로그인 성공 후 화면
.usernameParameter("email") // submit할 아이디
.failureUrl("/members/login/error")
.and()
.logout() // exception 필요
.logoutRequestMatcher(new AntPathRequestMatcher("/members/logout")) // 로그아웃 url
.logoutSuccessUrl("/"); // 로그아웃 후 이동할 화면
} catch (Exception e) {
throw new RuntimeException(e);
}
}
);
return http.build();
}
// 비밀번호 암호화
@Bean
public PasswordEncoder passwordEncoder(){
// 해수함수를 이용하여 비밀번호를 암호화하여 저장.
return new BCryptPasswordEncoder();
}
}
* 리다이렉션이 너무 많습니다.
원인 : url 마다 .permitAll()를 붙여줘야함.(SecurityConfig 수정 필요)
http.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/")
.usernameParameter("email")
.failureUrl("/login/error").permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll()
.logoutSuccessUrl("/");
3) LoginController.java 생성
- 로그인과 로그아웃 메소드를 생성합니다.
package won.shop.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequiredArgsConstructor
public class LoginController {
@GetMapping("/login")
public String loginForm(){
return "/member/login";
}
@GetMapping("/login/error")
public String loginError(Model model){
model.addAttribute("loginErrorMsg","아이디 또는 비밀번호를 확인해주세요.");
return "/member/login";
}
}
4) MainController.java 에서 로그인한 정보를 가져옵니다.
package won.shop;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class MainController {
@GetMapping("/")
public String main(@AuthenticationPrincipal User user, Model model){
if(user != null){
model.addAttribute("userName",user.getUsername());
}
return "/main";
}
}
- @AuthenticationPrincipal 을 이용해서 로그인한 정보를 model에 담아 화면에서 사용합니다.
728x90
반응형
'포토폴리오 > Spring-Boot,JPA - 쇼핑몰사이트 v2' 카테고리의 다른 글
#6. 고아 객체 제거 와 지연 로딩 (0) | 2023.08.04 |
---|---|
#5. 영속성 전이 (0) | 2023.08.04 |
#4. 연관 관계 매핑 (0) | 2023.08.04 |
#2. 스프링 시큐리티를 활용한 로그인/회원가입 (1) (0) | 2023.08.03 |
#0. 쇼핑몰 프로젝트 생성 (0) | 2023.08.02 |