Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

로그인 처리 본문

Project/블로그 게시판 만들기

로그인 처리

Seung__ 2021. 10. 4. 23:39

로그인 시 검증 처리를 위해 의존성 추가.

implementation 'org.springframework.boot:spring-boot-starter-validation'
  • 로그인을 벌써 구현하는 이유?
    • 세션에서 로그인 회원 정보를 가져와서, 글 작성시 작성자로 활용하기 위함

 

1. 로그인 방식


  • 쿠키
  • 세션

 

 

2. loginForm


  • 로그인 시 입력할 정보이다.
@Getter
@AllArgsConstructor
public class LoginForm {

    private String loginId;

    private String password;

}

 

 

3. loginService


  • 로그인 처리 로직은 간단하다 
  • 비밀번호가 DB에 입력된 값과 동일하면 Member정보를 반환한다.
  • 이 때 DTO로 변환하여 return.
@Service
@RequiredArgsConstructor
public class LoginService {

    private final MemberService memberService;

    public MemberDto login(String userId, String password){

        Member findMember = memberService.findMemberByUserId(userId);

        if(!findMember.getPassword().equals(password)){
            return null;
        }

        return findMember.memberToDto(findMember);

    }
}

 

 

 

 

4. SessionManager


  • 쿠키를 브라우저에 저장하지 않고 서버에 저장함.
  • 세션을 생성, 조회, 만료할 수 있는 SessionManager가 필요함.
  • @Component로 스프링 빈으로 등록한다.
  • 세션의 저장은 UUID, Value(저장할 객체 여기서는 로그인 회원)을 key & value로 Map에 저장.
  • 동시성 문제로 ConcurrentHashMap사용. 
  • Session Cookie name은 별도인터페이스에서 지정했음. 공용으로 사용.
/**
 * 세션 관리
 */
@Component
public class SessionManager {

    public static final String SESSION_COOKIE_NAME = "mySessionId";
    private Map<String, Object> sessionStore = new ConcurrentHashMap<>();

    /**
     * 세션 생성
     */
     public void createSession(Object value, HttpServletResponse response){

         String sessionId = UUID.randomUUID().toString();
         sessionStore.put(sessionId, value);

         Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
         response.addCookie(mySessionCookie);
     }

    /**
     * 세션 조회
     */
    public Object getSession(HttpServletRequest request){
        Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);

        if(sessionCookie == null){
            return null;
        }
        return sessionStore.get(sessionCookie.getValue());
    }

    /**
     * 세션 만료
     */
    public void expire(HttpServletRequest request){
        Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
        if(sessionCookie != null){
            sessionStore.remove(sessionCookie.getValue());
        }
    }

    public Cookie findCookie(HttpServletRequest request, String cookieName){
        Cookie[] cookies = request.getCookies();
        if(cookies == null){
            return null;
        }

        return Arrays.stream(cookies)
                .filter(cookie -> cookie.getName().equals(cookieName))
                .findAny()
                .orElse(null);
    }
}

 

 

5. LoginController


  • 전반적인 login의 흐름을 control
  • @Validated를 사용하면 @ModelAttribute에 바인딩되는 타입이 맞는지 검증됨.
  • BindingResult는 @ModelAttribute에 바인딩되는 파라미터의 바인딩 결과를 가지고 있음.
@Slf4j
@Controller
@RequiredArgsConstructor
public class LoginController {

    private final LoginService loginService;
    private final SessionManager sessionManager;

    @GetMapping("/login")
    public String loginForm(@ModelAttribute("loginForm") LoginForm form){
        return "login/loginForm";
    }


    @PostMapping("/login")
    public String login(@Validated @ModelAttribute("loginForm") LoginForm form,
                        BindingResult bindingResult, HttpServletResponse response){
        if(bindingResult.hasErrors()){
            return "login/loginForm";
        }

        MemberDto loginMember = loginService.login(form.getLoginId(), form.getPassword());
        if(loginMember == null){
            bindingResult.reject("loginFail", "id또는 pw정보가 맞지 않습니다.");
            return "login/loginForm";
        }

        //로그인 성공
        //세션으로 쿠키 처리.
        sessionManager.createSession(loginMember, response);

        return "redirect:/";
    }

    @PostMapping("/logout")
    public String logout(HttpServletRequest request){
        //세션이 없으면 null 반환
        HttpSession session = request.getSession(false);
        if(session!=null){
            session.invalidate();
        }
        return "redirect:/";
    }
    
}

 

 

6. 개발하며 발생한 문제점.


 

글을 작성하면 title, content가 서버로 넘어오지 않았다. 

 

글을 작성하는 form은 분명히 볼 수 있으나 입력 후 데이터가 바인딩 되지 않음.

 

원인을 찾다가 글 작성하는 form 보여주는 html파일 명과 return 에 적은 파일명이 달랐다.

 

  • 파일명 : addform.html
  • return "post/addForm"

~/post/new/form 접속시 파일명이 다르기 때문에 해당 페이지를 볼 수 없었으면 금방 찾았을 것 같은데..

 

페이지는 보이나 값이 안보여서 원인을 찾는데 오래 걸렸다.

 

처음에는 @ModelAttribute 오류인가, HTML의 form에서 문제가 있나...찾다가 한참걸림 ㅜ

 

아래와 같이 수정하고 나서는 정삭적으로 작동한다. 

    @GetMapping("/new/form")
    public String postForm(Model model, HttpServletRequest request) {
        MemberDto memberDto = (MemberDto) sessionManager.getSession(request);

        PostDto postDto = new PostDto();
        //postDto.setTitle("TitleTest");
        model.addAttribute("member", memberDto);
        model.addAttribute("post", postDto);

        return "post/addform";
    }
  • 그런데 왜 파일명이 일치하지 않았는데 addform.html은 어떻게 찾아간거니..

 

 

7. 해야할 일..


logout버튼을 클릭하면 자꾸 GET method로 요청이 간다...

        <button class="w-100 btn btn-dark btn-lg"
                th:onclick="|location.href='@{/logout}'|" type="submit" formmethod="post">
          로그아웃
        </button>
2021-10-04 23:32:03.354  WARN 25348 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver
: Resolved [org.springframework.web.HttpRequestMethodNotSupportedException
: Request method 'GET' not supported]

 

 

8. GitHub : 211004 Login


 

GitHub - bsh6463/blog

Contribute to bsh6463/blog development by creating an account on GitHub.

github.com

 

'Project > 블로그 게시판 만들기' 카테고리의 다른 글

home 버튼 추가  (0) 2021.10.05
로그아웃  (0) 2021.10.05
회원가입 개발  (0) 2021.10.04
도메인 모델, 연관관계  (0) 2021.10.03
댓글 도메인 개발  (0) 2021.10.03
Comments