https://magicmk.tistory.com/28
전편에 이은 회원가입 시 패스워드 암호화 및 회원 목록 조회다.
사실 전편보다 이번 내용을 먼저 구현했지만 왜 3번째인지 모르겠다. 😝
✅ 회원 목록 조회
우선 회원 목록 조회하는 내용부터 살펴보면
⏹️ MemberService
package com.practice.board.service;
import com.practice.board.dto.MemberSaveRequestDTO;
import com.practice.board.dto.MemberResponseDTO;
import org.springframework.validation.Errors;
import java.util.List;
import java.util.Map;
public interface MemberService {
/**
* 회원 목록 조회
* @return 회원 정보 목록
*/
List<MemberResponseDTO> findMembers();
}
인터페이스를 정의했으면 구현한다.
⏹️ MemberServiceImpl
package com.practice.board.service.Impl;
import com.practice.board.domain.Member;
import com.practice.board.dto.MemberSaveRequestDTO;
import com.practice.board.dto.MemberResponseDTO;
import com.practice.board.repository.MemberRepository;
import com.practice.board.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
@Override
public List<MemberResponseDTO> findMembers() {
List<Member> all = memberRepository.findAll();
List<MemberResponseDTO> members = new ArrayList<>();
for (Member member: all) {
MemberResponseDTO build = MemberResponseDTO.builder()
.member(member)
.build();
members.add(build);
}
return members;
}
}
repository에서 모든 정보를 찾아와 바로 member를 보내줄 수 있지만 그렇게 되면 전달하고 싶지 않은 내용도
유저에게 전달하기 때문에 DTO를 새로 생성하고 한번 필터링한 것을 볼 수 있다.
⏹️ MemberResponseDTO
package com.practice.board.dto;
import com.practice.board.domain.Member;
import lombok.*;
@Getter
@NoArgsConstructor
public class MemberResponseDTO {
private String email;
private String username;
@Builder
public MemberResponseDTO(Member member) {
this.email = member.getEmail();
this.username = member.getUsername();
}
}
해당 DTO에는 Entity를 DTO로 변환해야 하기 때문에 안에 Builder를 넣어줬다.
Service에서 가공을 마친 뒤 Controller에 데이터를 넘기면
⏹️ MemberController
package com.practice.board.controller;
import com.practice.board.dto.MemberResponseDTO;
import com.practice.board.dto.MemberSaveRequestDTO;
import com.practice.board.service.MemberService;
import com.practice.board.validator.CheckEmailValidator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PostMapping;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
@Controller
@RequiredArgsConstructor
@Slf4j
public class MemberController {
private final MemberService memberService;
private final CheckEmailValidator checkEmailValidator;
/**
* 회원 목록 조회
* @param model
* @return 회원 목록 페이지
*/
@GetMapping("/members")
public String members(Model model) {
List<MemberResponseDTO> members = memberService.findMembers();
model.addAttribute("members", members);
return "/members/memberList";
}
}
service에서 바로 받아와 model을 통해 view 페이지로 넘겨주면 된다. 너무 간단하다.
✅ 패스워드 암호화
이전까지 패스워드 암호화를 하지 않아 DB에 패스워드가 평문으로 들어가고 있는데 절대 이렇게 놔두면 안 되기 때문에
Spring Security에 있는 BCryptPasswordEncoder를 통해 암호화를 진행할 것이다.
우선 security 관련 라이브러리를 가져와야 한다.
⏹️ build.gradle
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-test'
그냥 security를 적용만 하면 서버를 띄워도 이상한 로그인 페이지가 나오고 불편하기 때문에 설정을 한다.
⏹️ SecurityConfig
package com.practice.board.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().disable() // cors 방지
.csrf().disable() // csrf 방지
.formLogin().disable() // 기본 로그인 페이지 없애기
.headers().frameOptions().disable();
return http.build();
}
}
예전에는 WebSecurityConfigurerAdapter를 override 해서 코드를 작성했지만 현재는 지원하지 않기 때문에
상속을 받지 않고 SecurityFilterChain을 통해 작성한다.
이렇게 작성한 뒤 Service로 돌아가서 회원가입 로직을 작성하면 끝이다.
⏹️ MemberServiceImpl
package com.practice.board.service.Impl;
import com.practice.board.domain.Member;
import com.practice.board.dto.MemberSaveRequestDTO;
import com.practice.board.dto.MemberResponseDTO;
import com.practice.board.repository.MemberRepository;
import com.practice.board.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
@Override
public Long join(MemberSaveRequestDTO memberSaveRequestDTO) {
memberSaveRequestDTO.setPassword(passwordEncoder.encode(memberSaveRequestDTO.getPassword()));
Member member = Member.builder()
.email(memberSaveRequestDTO.getEmail())
.username(memberSaveRequestDTO.getUsername())
.password(memberSaveRequestDTO.getPassword())
.build();
return memberRepository.save(member).getId();
}
}
원래는 PasswordEncoder의 생성자를 작성하고 해야한다.
@RequiredArgsConstructor의 엄청난 힘으로
private final PasswordEncoder passwordEncoder;
위처럼 작성해주면 사용할 수 있다.
끝.
'Java > Spring Boot 게시판' 카테고리의 다른 글
spring boot 게시판 - 6 <bootstrap 적용하기> (0) | 2022.11.22 |
---|---|
spring boot 게시판 - 5 <thymeleaf layout 적용> (0) | 2022.11.21 |
spring boot 게시판 - 4 <spring security form login 구현> (0) | 2022.11.18 |
spring boot 게시판 - 2 <회원 중복 체크 및 유효성 검사> (0) | 2022.11.11 |
Spring boot 게시판 - 1 < 간단 회원 가입 구현> (8) | 2022.11.10 |