Back-End/Spring

[Spring MVC2][로그인 처리] - 로그인 기능(로그인 서비스 로직)

얄루몬 2022. 5. 13. 14:19

💻본 포스팅은 '스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 김영한'님의 강의를 듣고 작성되었습니다.

https://inf.run/vQHp

 

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의

웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

www.inflearn.com


[로그인 처리와 관련한 디렉토리 배치 설명]

  • 로그인 판단 로직(핵심)
    • 로그인의 핵심 로직으로 로그인의 성공, 실패 여부를 확인하기 위한 부분으로 domain 디렉토리 하위에 배치해준다.
  • 그 외에 로그인 관련 로직
    • 컨트롤러와 로그인 관련 객체를 web 디렉토리 하위에 넣어준다.

 

[로그인 기능]

[서비스 로직 - 로그인 성공 실패 여부 판단 로직]

[람다 스트림 X]

package hello.login.domain.login;

import hello.login.domain.member.Member;
import hello.login.domain.member.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class LoginService {

    private final MemberRepository memberRepository;

    //return null이면 로그인 실패
    public Member login(String loginId, String password){
        Optional<Member> findMemberOptional = memberRepository.findByLoginId(loginId);

        //Optional의 get = member 안에 있는 걸 꺼내 나오고 없으면 예외터짐
        Member member = findMemberOptional.get();
        if (member.getPassword().equals(password)){
            return member;
        }else{
            return null;
        }

    }
}

 

[람다 스트림 O]

package hello.login.domain.login;

import hello.login.domain.member.Member;
import hello.login.domain.member.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class LoginService {

    private final MemberRepository memberRepository;

    //return null이면 로그인 실패
    public Member login(String loginId, String password){
        return memberRepository.findByLoginId(loginId)
                .filter(m -> m.getPassword().equals(password))
                .orElse(null);
    }
}

[로그인 폼]

package hello.login.web.login;


import lombok.Data;

import javax.validation.constraints.NotEmpty;

@Data
public class LoginForm {

    @NotEmpty
    private String loginId;

    @NotEmpty
    private String password;


}

[컨트롤러]

package hello.login.web.login;


import hello.login.domain.login.LoginService;
import hello.login.domain.member.Member;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Objects;
@Slf4j
@Controller
@RequiredArgsConstructor
public class LoginController {
    private final LoginService loginService;
    @GetMapping("/login")
    public String loginForm(@ModelAttribute("loginForm") LoginForm form) {
        return "login/loginForm";
    }
    @PostMapping("/login")
    public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "login/loginForm";
        }
        Member loginMember = loginService.login(form.getLoginId(),
                form.getPassword());
        log.info("login? {}", loginMember);
        if (loginMember == null) {
            bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
            return "login/loginForm";
        }
        //로그인 성공 처리 TODO
        return "redirect:/";
    }
}

 

[정리]

  • 로그인 구현까지는 어렵지 않았다. 이때 로그인 성공 여부를 판단하는 로직은 web이 바뀌어도 바뀌면 안 되는 핵심 비지니스 영역으로 domain에 배치시켜 주었다.
  • 또한 Optional을 사용해 global 에러를 다뤘고 이때 bindingResult.reject( )를 사용했다.  
  • 다음으로는 로그인을 진행했을 때 개인화를 위한 방법을 알아볼 것이다.(로그인 처리 기능에 쿠키를 사용해보자.)