쿠키-세션을 이용하지않고 우선 단순히 회원가입과 로그인 기능을 구현할 것이다.
기본적은 동작이 다 가능해지면 그때 쿠키와 세션의 개념을 도입해서 코드를 리팩토링할 예정이다.
회원 생성, 조회, 수정, 삭제 기능 중 우선 회원 생성 및 조회기능만 구현하겠다.
@Data
public class User {
private Long id; // db 식별자
@NotBlank(message = "아이디를 입력해주세요.")
private String loginId; // 로그인 아이디
@NotBlank(message = "이름을 입력해주세요.")
private String name; // 사용자 이름
@NotBlank(message = "비밀번호를 입력해주세요.")
private String password; // 비밀 번호
}
이 부분도 나중에 저장 방식을 전환할 수 있기 때문에 Repository를 인터페이스로 구현하고 구현체로는 InMemory 방식으로 구현했다.
public interface UserRepository {
Long save(User user);
User findById(Long id);
List<User> findAll();
Optional<User> findByLoginId(String loginId);
// 회원 정보 수정
// 회원 탈퇴
}
@Repository
public class UserRepositoryImpl implements UserRepository {
private static Map<Long, User> store = new HashMap<>();
private static long sequence = 0L;
@Override
public Long save(User user) {
user.setId(++sequence);
store.put(user.getId(), user);
return user.getId();
}
@Override
public User findById(Long id) {
User user = store.get(id);
return user;
}
@Override
public List<User> findAll() {
return new ArrayList<>(store.values());
}
@Override
public Optional<User> findByLoginId(String loginId) {
List<User> Users = findAll();
for (User user : Users) {
if (user.getLoginId().equals(loginId)){
return Optional.of(user);
}
}
return Optional.empty();
}
}
}
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
// 회원가입(생성)
public Long save(User user){
Long saveUserId = userRepository.save(user);
return saveUserId;
}
// 회원 조회
public User findById(Long id){
User user = userRepository.findById(id);
return user;
}
public List<User> findAll() {
List<User> users = userRepository.findAll();
return users;
}
public Optional<User> findByLoginId(String loginId){
Optional<User> user = userRepository.findByLoginId(loginId);
return user;
}
// 회원 정보 수정
// 회원 탈퇴(삭제)
}
@Controller
@RequiredArgsConstructor
@RequestMapping("/add")
public class UserController {
private final UserService UserService;
// 회원가입 폼 보여주기
@GetMapping("/user")
public String addUserForm(Model model){
model.addAttribute("user", new User());
return "login/addForm";
}
// 회원가입 하기
@PostMapping("/user")
public String addUser(@Validated @ModelAttribute User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "login/addForm";
}
UserService.save(user);
return "login/home";
}
}
@Data
public class Login {
@NotBlank(message = "아이디를 입력해주세요.")
private String loginId;
@NotBlank(message = "비밀번호를 입력해주세요.")
private String password;
}
@Service
@RequiredArgsConstructor
public class LoginService {
private final UserService userService;
public User login(String loginId, String password) {
Optional<User> findUserByLoginID = userService.findByLoginId(loginId);
User user = findUserByLoginID.get();
if (user.getPassword().equals(password)) {
// 로그인 성공
return user;
}
// 로그인 실패
return null;
}
}
- UserService에서 구현한 findbyLoginId를 통해 사용자가 입력한 로그인 아이디를 가지고 회원을 찾고, 찾은 회원의 비밀번호는 getPassword()를 통해 가져온다.
@PostMapping("/login")
public String login(@Validated @ModelAttribute Login login, BindingResult bindingResult){
if (bindingResult.hasErrors()){
return "login/loginForm";
}
Optional<User> addUserCheck = userService.findByLoginId(login.getLoginId());
if (addUserCheck.isEmpty()) {
bindingResult.reject("addFail", "존재하지 않는 회원입니다. 회원가입을 해주세요.");
return "login/loginForm";
}
User loginUser = loginService.login(login.getLoginId(), login.getPassword());
if (loginUser == null) {
// 로그인 인증 과정에서 오류가 발생했을 때,
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다. 다시 입력해주세요.");
return "login/loginForm";
}
return "redirect:/library";
}
id는 spring, pwd : spring 입력시
아직 쿠키-세션 기능은 도입하지 않았으며 회원 탈퇴, 회원 정보 수정, 아이디 중복 확인 등의 로직은 구현하지 않았다.
우선 기본적인 회원가입 및 로그인 기능은 구현했으니 점차 추가할 생각이다.
디자인도 좀 해야겠다.........