카테고리 없음

[Spring Security] JWT Tutorial (4) - 회원가입 & 권한검증

엥재 2023. 6. 17. 18:55

이번 포스팅에서는 마지막으로 회원 가입을 통해 데이터베이스에 회원 정보를 저장하고, 로그인을 통해 JWT를 생성하여, 권한에 따른 리소스에 접근 시 발급받은 JWT를 통해 검증하고 접근하는 로직을 개발해보자.

 

먼저 회원가입 로직을 개발하기 위해서 MemberService를 구현하자.

MemberService

 

[ SecurityUtil ] 

먼저, MemberService를 구현하기 앞서, 현재 유저의 이름을 반환하는 메서드를 가지고 있는 클래스를 생성하자.

public class SecurityUtil {
    private static final Logger logger = LoggerFactory.getLogger(SecurityUtil.class);
    private SecurityUtil(){
    }
    public static Optional<String> getCurrentUsername(){
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if(authentication == null){
            logger.info("Security Context에 인증 정보가 없습니다.");
            return Optional.empty();
        }

        String username = null;
        if(authentication.getPrincipal() instanceof UserDetails){
            UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
            username = springSecurityUser.getUsername();
        }else if(authentication.getPrincipal() instanceof String){
            username = (String) authentication.getPrincipal();
        }
        return Optional.ofNullable(username);
    }
}

 

[ MemberService ]

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberService {
    private final MemberRepository memberRepository;
    private final PasswordEncoder passwordEncoder;;

    // 회원가입 로직으로, 일반 회원이므로 ROLE_USER 권한
    @Transactional
    public Member signup(MemberDto memberDto){
        if(memberRepository.findOneWithAuthoritiesByUsername(memberDto.getUsername()).orElse(null) != null){
            throw new RuntimeException("이미 가입되어 있는 회원입니다.");
        }
        Authority authority = Authority.builder()
                .authorityName("ROLE_USER")
                .build();

        Member member = Member.builder()
                .username(memberDto.getUsername())
                .password(passwordEncoder.encode(memberDto.getPassword()))
                .nickname(memberDto.getNickname())
                .authorities(Collections.singleton(authority))
                .activated(true)
                .build();

        return memberRepository.save(member);
    }

    // 유저이름으로 유저 객체와 권한정보 가져옴
    public Optional<Member> getUserWithAuthorities(String username){
        return memberRepository.findOneWithAuthoritiesByUsername(username);
    }

    // SecurityContext에 저장된 username의 정보만 가져옴
    public Optional<Member> getMyUserWithAuthorities(){
        return SecurityUtil.getCurrentUsername().flatMap(memberRepository::findOneWithAuthoritiesByUsername);
    }
}
  • signup() 메서드를 통해 회원가입을 진행 (일반 유저 이므로 ROLE_USER로 설정)
  • getUserWithAuthorities()를 통해 유저 이름으로 유저 객체와 권한정보를 가져옴
  • getMyUserWithAuthorities() 를 통해  SecurityContext에 저장된 username의 정보만 가져옴

 

마지막으로 회원가입을 요청할 컨트롤러 계층을 개발해보자.


MemberController

@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class MemberController {

    private final MemberService memberService;

    @PostMapping("/signup")
    public ResponseEntity<Member> signup(@Valid @RequestBody MemberDto memberDto){
        return ResponseEntity.ok(memberService.signup(memberDto));
    }

    @GetMapping("/user")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Member> getMyMemberInfo(){
        return ResponseEntity.ok(memberService.getMyUserWithAuthorities().get());
    }

    @GetMapping("/user/{username}")
    @PreAuthorize("hasAnyRole('ADMIN')")
    public ResponseEntity<Member> getMemberInfo(@PathVariable String username){
        return ResponseEntity.ok(memberService.getUserWithAuthorities(username).get());
    }
}
  • "/api/signup" 
    • memberService를 통해 RequestBody를 통해 MemberDto 정보로 회원가입을 진행
    • 성공하면 ResponseEntity에 담아 리턴
  • "/api/user" 
    • @PreAuthorize : USER, ADMIN으로 두 개의 권한 중 하나라도 가지면 접근이 가능
    • 현재 member의 정보를 조회하는 API
  • "/api/user/{username}"
    • @PathVariable : username
    • @PreAuthorize : ADMIN
    • 회원 정보를 username을 통해 검색하는 API

< 참고 자료 >

 

[무료] Spring Boot JWT Tutorial - 인프런 | 강의

Spring Boot, Spring Security, JWT를 이용한 튜토리얼을 통해 인증과 인가에 대한 기초 지식을 쉽고 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com