로그인 1

강한친구·2022년 6월 20일
0

Spring

목록 보기
21/27

로그인 요구조건

  1. 로그인 화면
  2. 로그인 성공 전용 화면
  3. 로그인 된 사용자만이 수정 가능

패키지 설계

웹 기술이 바뀌더라도, 도메인은 살아있어도록 설계를 해야한다. 따라서 웹은 도메인에 의존해도, 도메인은 웹에 의존하지 않도록 설계를 해야한다.

회원 가입 구현

멤버 객체나 맴버 리포지토리는 구현되어 있다는 가정 하에 진행하겠다.

우선 회원가입 form을 get하고 model을 post하는 controller를 구현해야한다.

    @GetMapping("/add")
    public String addForm(@ModelAttribute("member") Member member) {
        return "members/addMemberForm";
    }

    @PostMapping("/add")
    public String save(@Validated @ModelAttribute Member member, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "members/addMemberForm";
        }

        memberRepository.save(member);
        return "members/addMemberForm";
    }

postMapping에서는 form에 입력된 값을 받아서 member 객체로 만들고 이를 memberRepository에 저장해준다.

이로써 간단한 회원가입 구현은 완료되었다.

로그인 구현

로그인의 검증과정은 다음과 같다.

  1. Controller가 로그인 화면 호출
  2. 사용자가 입력 후 post로 전달
  3. 입력받은 id, password를 받아서 해당하는 member가 있는지 검색
  4. member가 있다면 password가 일치하는지 확인
  5. 일치하면 로그인처리, 실패하면 오류메시지

Controller

 	@PostMapping("/login")
    public String login(@Validated @ModelAttribute LoginForm form, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "login/loginForm";
        }
        Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

LoginForm이라는 분리된 Form을 받고, 그 form안에 있는 정보를 loginService.login으로 보내서 검증을 시도한다.

loginService

public Member login(String loginId, String password) {
        return memberRepository.findByLoginId(loginId)
                .filter(m -> m.getPassword().equals(password))
                .orElse(null);
    }

서비스에서는 로그인 아이디와 비밀번호를 가지고 lambda식을 이용해서 memberRepository에서 조회 후, member return 혹은 null을 리턴한다.

쿠키 적용

로그인처리 하고 쿠키로 만들어놔야지 웹 브라우저와 서버가 서로 로그인 상태라고 인식할 수 있다.

Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
response.addCookie(idCookie);
return "redirect:/";

세션쿠키를 만들어서 이 값을 HttpResponse에 넣어준다.

그러면 이렇게 cookie가 생성된다.

그러고 나면, homeController에서

 @GetMapping("/")
    public String homeLogin(
            @CookieValue(name = "memberId", required = false) Long memberId, Model model) {}

쿠키밸류를 이용해서 로그인전용 홈페이지를 보여줄 수 있다.

로그아웃 구현

로그아웃 버튼을 누르면 쿠키를 만료시켜서 로그인상태를 해제해야한다. 따라서 Max_age를 0으로 만드는 controller를 추가한다.

	@PostMapping("/logout")
    public String logout(HttpServletResponse response) {
        expireCookie(response, "memberId");
        return "redirect:/";
    }

이런식으로 쿠키를 날려주면 로그인 상태가 풀리게 된다.

보안 주의
이런방식은 보안상 큰 문제가 있다.

쿠키 위조

현재 1번 아이디를 가진 tester 계정과 2번을 가진 tester2가 존재한다. 이때, tester가 로그인 해 있는 상태이다.

하지만 이런식으로 유저는 쿠키값을 아주 자유롭게 변경이 가능하다.

이러면 다른 유저로 로그인이 되어버린다...

세션 id

  1. 사용자가 id, pw 정보를 전달하면 서버에서 사용자가 맞는지 검증

  2. UUID는 추정이 불가능하다. 따라서 uuid를 사용한다.

  3. 생성된 id와 새션에 보관할 값을 서버의 세션 저장소에 보관한다.

  4. 쿠키를 만들어서 전달하는데 세션id만 담은 mySessionId를 만들어서 전달한다.

  5. 클라이언트는 이를 저장한다.

6.클라이언트는 요청시 항상 mySessionId 쿠키를 전달한다.
서버에서는 클라이언트가 전달한 mySessionId 쿠키 정보로 세션 저장소를 조회해서 로그인시 보관한세션 정보를 사용한다

클라이언트사이드에서는 쿠키값을 변조하더라도 다른 회원 세션과 중복될 일이 거의 없어서 변조문제가 없어지며, 클라이언트가 쿠키를 타루치해도 시간이 지나면 세션만료로 인하려 사용할 수가 없다.

또한 서버가 해킹위험을 감지하면 세션을 제거해서 무효화 할 수 도 있다.

0개의 댓글