그램그램 - 회원가입과 로그인 구현

JIWOO YUN·2024년 5월 14일
0

GramGram

목록 보기
3/11
post-custom-banner

해야할 일

-  회원가입 폼
    -  폼이 있어야 한다.
    -  input[name="username"] 필드가 있어야 한다.
    -  input[name="password"] 필드가 있어야 한다.
    - 폼 체크
-  회원가입 폼 처리
    -  유효성 체크를 해야 한다.
    -  member 테이블에 회원이 저장되어야 한다.
    -  처리 후에 / 로 이동해야 한다. 302

폼을 이용해서 최소와 최대 제한 글자를 통해서 제한

@AllArgsConstructor
@Getter
public class JoinForm {

    @NotBlank
    @Size(min = 4,max = 20)
    private final String username;

    @NotBlank
    @Size(min = 4, max = 30)
    private final String password;
}
  • 유저이름은 최소 4자부터 최대 20자
  • 비밀번호의 경우에도 최소 4자에서 30자로 제한.

javsScript를 활용해서 script를 통해 현재 폼이 유효한지 확인하는 방식을 사용할 예정

function JoinForm__submit(form){
    form.username.value = form.username.value.trim();


    if(form.username.length == 0){
        alert('아이디를 입력해주세요.');
        form.username.focus();
        return;
    }

    if(form.username.length < 4 || form.username.length > 20){
        alert('아이디를 4자 이상 20자 이하로 입력해주세요.');
        form.username.focus();
        return;
    }

    form.password.value = form.password.value.trim();

    if(form.password.length == 0){
        alert("비밀번호를 입력해주세요.");
        form.password.focus();
        return;
    }

    if(form.password.length < 4 || form.password.length > 30){
        alert("비밀번호는 4자 이상 30자이하로 입력해주세요.");
        form.password.focus();
        return;
    }

    form.submit();
}
  • join.html에 검증 스크립트를 추가

  • 실수 했던 부분

    • 자바스크립트에 익숙하지 않아서 생긴 문제로 input 태그타입을 참조하고 있는 form의 경우 input 태그 자체게 length 속성이 존재하지 않기 때문에 사용자가 입력한 값의 길이를 확인하려면 value 속성을 사용하여 해당 입력값에 접근한 후 이 값의 length를 검사해야하는 점을 몰라서 헤맸다.

Member 테이블에 회원이 저장되어야한다

  • 회원이 저장되기 위해서 필요한 것들
    • member 객체
    • member를 저장할 memberRepository
    • memberRepository에 접근할 memberService

member 객체를 빌더로 만들어 둠으로써 유연성을 확보하자.

  • 아직 인스타관련해서 적용을 하지않았기 때문에 추후에 적용을 위해서 builder를 사용해서 유연성확보
  • setter의 위험성을 배제
@Getter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
@ToString
public class Member {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;

    private String username;

    private String password;

    @CreatedDate
    private LocalDateTime createDate;

    @LastModifiedDate
    private LocalDateTime modifyDate;

}

로그인 구현

#할일
로그인 폼 추가하기
로그인 상태에서는 회원가입 폼에 갈 수 없게
로그인 폼 체크 필요

-  레이아웃 네비바 구현
  -  로그인 버튼
  -  회원가입 버튼
  -  로그아웃 버튼

로그인을 하기위해서 필요한 작업

  • 로그인을 하기위한 폼 추가
    • thymeleaf를 이용한 form 처리 방법
    • 마찬가지로 여기서 비어있는지 정도만 자바스크립트를 통해서 확인

로그인 폼 자체는 회원가입 폼이랑 그렇게 차이가 없다

  • 공통적으로 발생하는 부분이 존재하게 되기 때문에 공용템플릿으로 layout묶어주기.

layout 공용 템플릿

  • toastr을 사용하여 꾸미기
  • toastr를 사용하기 위해서는 jquery가 필요하기 때문에 추가
<html>

<head>

    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js"></script>
    <link rel="stylesheet" href="https://jhs512.github.io/toastr/toastr.css">

    <script>
    toastr.options = {
      closeButton: true,
      debug: false,
      newestOnTop: true,
      progressBar: true,
      positionClass: "toast-top-right",
      preventDuplicates: false,
      onclick: null,
      showDuration: "300",
      hideDuration: "1000",
      timeOut: "5000",
      extendedTimeOut: "1000",
      showEasing: "swing",
      hideEasing: "linear",
      showMethod: "fadeIn",
      hideMethod: "fadeOut"
    };

    function toastNotice(msg) {
      toastr["success"](msg, "알림");
    }

    function toastWarning(msg) {
      toastr["warning"](msg, "알림");
    }
  </script>

    <style>
    @font-face {
      font-family: 'GmarketSansMedium';
      src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/GmarketSansMedium.woff') format('woff');
      font-weight: normal;
      font-style: normal;
    }

    html > body {
      font-family: "GmarketSansMedium";
      text-underline-position: under;
    }
  </style>

</head>

<body>

<link href="https://cdn.jsdelivr.net/npm/daisyui@2.51.5/dist/full.css" rel="stylesheet" type="text/css"/>
<script src="https://cdn.tailwindcss.com"></script>

<main layout:fragment="main"></main>

</body>

</html>

로그인 부분은 UserDetailService를 통해서 이미 구현이 되있는 부분

  • SrpingSecurity에서 제공하는 로그인 기능
  • 기본적으로 권한을 위한 Collection<? extends GrantedAuthority> authorities 이부분이 필요하다.
    • 사용권한을 식별하고 무언가에 대한 엑세스를 허용하는 지 여부를 결정하는데 사용가능.

CustomUserDetailService

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class CustomUserDetailService implements UserDetailsService {

    private final MemberRepository memberRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Member member = memberRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("username(%s) not found".formatted(username)));


        return new User(member.getUsername(), member.getPassword(), member.getGrantedAuthorities());
    }
}

메인 홈페이지 추가 및 로그인여부 확인

  • layout을 이용하여 /home/main.html 추가

로그인 여부 확인 방법

  • 로그인 성공시에 session에 해당 데이터를 넣어주기 때문에 로그인 여부를 확인할 수 있음.
<header>
    <a href="/member/login" sec:authorize="isAnonymous()" class="btn btn-link">로그인</a>
    <a href="/member/join" sec:authorize="isAnonymous()" class="btn btn-link">회원가입</a>
    <a href="javascript:;" sec:authorize="isAuthenticated()" onclick="$(this).next().submit();" class="btn btn-link">로그아웃</a>
    <form th:action="|/member/logout|" method="POST"></form>
</header>
  • 공용 layout 부분에서 sec authoirize를 통해서 로그인이되어잇다면 로그아웃만 보이게 되고 로그인이 되어있지않다면 로그인과 회원가입이 보인다.

진행된 PR


참조 블로그 또는 문헌

빌터 패턴 참조 블로그 : https://mangkyu.tistory.com/163

빌터 패턴 doc : https://projectlombok.org/api/lombok/Builder

Collection<? extends GrantedAuthority> authorities 이해하기위한 참조 :

https://stackoverflow.com/questions/19525380/difference-between-role-and-grantedauthority-in-spring-security

profile
열심히하자
post-custom-banner

0개의 댓글