6. 회원가입 및 인증메일

kdew0308·2023년 3월 19일
0

학습 관리 시스템

목록 보기
6/17

1. 프로젝트 생성과 깃커밋

  • 실명인증, 전화번호 인증 샘플들을 테스트하기 편한게 war

1-1) Maven

clean : 만들어진 내용에 대해서 clean하는 것임. 타겟을 지우는 것
package : 타겟에 필요한 파일을 컴파일하고 패키징 하는 것

1-2) 기본 파일 설명

DewlmsApplication : main을 run 하는 파일
serveltinitializer : 서블릿을 인식해줌


application.properties -> application.yml로 이름 변경

1-3) 깃 등록

  1. VCS -> Enable Version Control Integration -> Git선택

  2. commit 버튼 클릭

  3. gitignore 수정 후 다시 커밋

    /.idea/
    /.mvn/
    /mvnw
    /mvnw.cmd

  4. push
    저장소가 없는 경우!
    Git -> Share Project On GitHub

  5. 수정한 내용 push 할 때
    commit -> push

2. 스프링 콘트롤과 주소 매핑

2-1) MainPage

  • MainPage 클래스를 만든 목적 : 매핑하기 위함
  • 주소(논리적인 인터넷 주소)와 물리적인 파일(프로그래밍을 해야하기 때문)을 매핑하기 위해
  • 메소드를 통해서 주소를 매핑함
  • 어노테이션을 통해서 매핑을 해줌 : @RequestMapping()

예제1

@RestController
public class MainPage {
    @RequestMapping("/")
    public String index() {
        return "Index Page";
    }
}

예제2

@RequestMapping("/hello")
    public String Hello() {
        return "Hello!";
    }

예제3

@RequestMapping("/dewlms")
    public String hello() {
        String msg = "<p>hello</p> <p>dewlms website!!!</p>";
        return msg;
    }

3. Response 객체를 이용한 HTML 작성

3-1) @Controller

  • return 값이 String이면 에러 뜸
  • HttpServletRequest request, HttpServletResponse response 이런 것들이 필요

3-2) request 객체

  • request : 웹에서 서버로 데이터를 보내기 위해서 사용

3-3) response 객체

  • response : 서버에서 웹으로 보내기 위해서 사용
@RequestMapping("/dewlms")
    public void hello(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter printWriter = response.getWriter();
        
        String msg = "<html>" +
                "<head>" +
                "</head>" +
                "<body>" +
                "<p>hello</p> <p>dewlms website!!!</p>" +
                "</body>" +
                "</html>";
        
        printWriter.write(msg);
        printWriter.close();
    }

3-4) 한글깨짐 해결

@RequestMapping("/dewlms")
    public void hello(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter printWriter = response.getWriter();

        String msg = "<html>" +
                "<head>" +
                "<meta charset=\"UTF-8\">" +
                "</head>" +
                "<body>" +
                "<p>hello</p> <p>dewlms website!!!</p>" +
                "<p> 안녕하세요!!! </p>" +
                "</body>" +
                "</html>";

        printWriter.write(msg);
        printWriter.close();
    }

4. Thymeleaf를 통한 view 페이지 매핑

4-1) templates

resources -> templates 폴더 안에 html 파일로 작성

index.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1> 인덱스 페이지 !!! </h1>
    <p> 안녕하세요.</p>
</body>
</html>

MainPage.java

@RequestMapping("/")
    public String index() {
        return "index";
    }

자동으로 index.html이 매핑이 됨

만약 index.htmlresources -> templates -> member 폴더 안에 있으면 return "member/index";

자동으로 매핑되는 이유!

디폴트가 .html파일과 classpath:/templates/ 이기 때문

만약 위치를 바꾸고 싶으면
application.yml 파일에

spring:
  thymeleaf:
    suffix: .jsp
    prefix: .classpath:/temp/

이러면 temp 폴더 안에 jsp 파일들을 매핑함

5. 회원가입 입력 폼 HTML 작성과 서버 전송

  • <form><name>은 필수
  • <form method="post"> : 디폴트는 get방식
  • @GetMapping : get방식만 받을 수 있음
  • @PostMappting : POST로만 받을 수 있음

5-1) 옛날 방식 POST와 GET

처음 화면에 접속하면 GET이 실행
전송 버튼을 눌렀을 때 POST 실행

메소드 하나는 @RequestMapping(value = "/member/register", method = RequestMethod.GET)
나머지는 @RequestMapping(value = "/member/register", method = RequestMethod.POST)

@RequestMapping(value = "/member/register", method = RequestMethod.GET)
public String register() {

        return "member/register";
}

@RequestMapping(value = "/member/register", method = RequestMethod.POST)
public String registersubmit() {

        return "member/register";
}

5-2) 기본 실습

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>회원 가입</title>
</head>
<body>
<h1>회원 가입</h1>
    <form method="post">
        <div>
            <input type="email" name="userId" placeholder="아이디(이메일) 입력" required/>
        </div>
        <div>
            <input type="text" name="userName" placeholder="이름 입력" required />
        </div>
        <div>
            <input type="password" name="password" placeholder="비밀번호 입력" required />
        </div>
        <div>
            <input type="password" name="rePassword" placeholder="확인 비밀번호 입력" required />
        </div>
        <div>
            <input type="tel" name="phone" placeholder="전화번호 입력" required />
        </div>
        <div>
            <button>회원 가입 하기</button>
        </div>
    </form>
</body>
</html>

MemberController.java

@Controller
public class MemberController {

    @GetMapping("/member/register")
    public String register() {

        return "member/register";
    }

    @PostMapping("/member/register")
    public String registerSubmit(HttpServletRequest request, HttpServletResponse response) {
        String userId = request.getParameter("userId");
        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        String phone = request.getParameter("phone");

        System.out.println("userId:" + userId);
        System.out.println("userName:" + userName);
        System.out.println("password:" + password);
        System.out.println("phone:" + phone);

        return "member/register";
    }
}

5-3) 더 간단하게

MemberController.java

@Controller
public class MemberController {

    private final MemberRepository memberRepository;

    public MemberController(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
    @GetMapping("/member/register")
    public String register() {

        return "member/register";
    }

    @PostMapping("/member/register")
    public String registerSubmit(HttpServletRequest request, HttpServletResponse response
        , MemberInput parameter) {

        System.out.println(parameter.toString());

        Member member = new Member();
        member.setUserId(parameter.getUserId());
        member.setPassword(parameter.getPassword());
        member.setPhone(parameter.getPhone());
        member.setUserName(parameter.getUserName());
        member.setRegDt(LocalDateTime.now());
        memberRepository.save(member);

        return "member/register_complete";
    }

}

member 폴더 안에 MemberInput.java

@ToString
@Data
public class MemberInput {

    private String userId;
    private String userName;
    private String password;
    private String phone;
}

6. 회원가입_POST_SUBMIT된 내용_JPA를 통한 DB 저장

6-1) 라이브러리 가져오기

새프로젝트 만들어서 가져오기!

만들어진 프로젝트에서 pom.xml 들어가서 jpa와 jdbc 내용 복사해서 lms에 붙여넣기!

6-2) 드라이브 등록

등록 하기 전에 URL 주소 복사해서 apllication.yml에 붙여넣기!
apllication.yml

spring:
  datasource:
    url: jdbc:mariadb://본인아이피:43306/minicampus
    driver-class-name: org.mariadb.jdbc.Driver
    username: minicampus_user
    password: a1234
    
   jpa:
    generate-ddl: true
    hibernate:
      ddl-auto: update
    show-sql: true

generate-ddl: true : 테이블 자동으로 만들어줄것이냐!
show-sql: true : 로그할때 보기 편함

MemberInput.java 위치 이동 : member.model
MemberController.java 위치 이동 : member.controller

6-3) Entity생성해서 데이터베이스 자동 생성

위치 : .member.entity
Member.java

@Data
@Entity ` ㅌ`~
public class Member {
    @Id
    private String userId;

    private String userName;
    private String phone;
    private String password;
    private LocalDateTime regDt; // 회원가입 날짜

}

6-4) 레포지토리 생성

위치 : .member.repository
MemberRepository.java

public interface MemberRepository extends JpaRepository<Member, String> {

}

7. JavaMailSender를 통한 메일 전송 설정 및 메일 전송 테스트(Gmail)

7-1) 라이브러리 가져오기

이메일 인증하기 버튼을 클릭하면 메일이 전송됨 -> 그 인증 메일을 타고 들어왔을 때 회원가입 가능


복사!

붙여넣기!

7-2) 메일을 받기 위한 설정

  1. 계정관리 -> 보안 -> 2단계 인증 설정 -> 앱 비밀번호 설정 -> 비밀번호 복사
  1. .idea 폴더 안에 smtp.txt 파일 만들고 거기에 기기용 앱 비밀번호 복붙

  2. gmail에서 설정 -> 모든 설정 보기 -> 전달 및 POP/IMAP -> POP 다운로드와 IMAP 액세스 설정

    이렇게 되어있는 것을

    이렇게 설정

  3. application.yml 안에

mail:
  host: smtp.gmail.com
  port: 587
  username: kdew0308@gmail.com
  password: 비밀번호입력
  properties:
    mail:
      smtp:
        starttls:
          enable: true

8. 회원가입 후 메일 전송

components -> MailComponents.java

@RequiredArgsConstructor
@Component
public class MailComponents {

    private final JavaMailSender javaMailSender;

    public void sendMailTest() {
        SimpleMailMessage msg = new SimpleMailMessage();
        msg.setTo("kdew0308@naver.com"); // 누구한테 보낼 것인지
        msg.setSubject("안녕하세요!"); // 제목
        msg.setText("안녕하세요 반갑습니다!"); // 내용

        javaMailSender.send(msg);
    }
}

MainController.java

@RequiredArgsConstructor
@Controller
public class MainController {

    private final MailComponents mailComponents;


    @RequestMapping("/")
    public String index() {
        mailComponents.sendMailTest();

        return "index";
    }
  }

에러 발생

Consider defining a bean of type 'org.springframework.mail.javamail.JavaMailSender' in your configuration

해결

config 폴더 만든 후

@Configuration
public class MailConfig {
    @Bean
    public JavaMailSender javaMailService() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setHost("smtp.gmail.com");
        javaMailSender.setPort(587);
        javaMailSender.setUsername("kdew0308@gmail.com");
        javaMailSender.setPassword("비밀번호");

        //세부사항
        Properties prop = new Properties();
        prop.setProperty("mail.transport.protocol", "smtp");
        prop.setProperty("mail.smtp.auth", "true");
        prop.setProperty("mail.smtp.starttls.enable", "true");
        prop.setProperty("mail.debug", "true");
        javaMailSender.setJavaMailProperties(prop);

        return javaMailSender;
    }

}

생성

8-1) 더 디테일하게 메일 보내기!

MailComponents.java

// sendMail 함수 추가!

public boolean sendMail(String mail, String subject, String text) {
        boolean result = false;
        MimeMessagePreparator msg = new MimeMessagePreparator() {
            @Override
            public void prepare(MimeMessage mimeMessage) throws Exception {
                MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
                mimeMessageHelper.setTo(mail);
                mimeMessageHelper.setSubject(subject);
                mimeMessageHelper.setText(text, true);

            }
        };

        try {
            javaMailSender.send(msg);
            result = true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        // 디테일하게 메일 보내기
        return result;
    }

MainController.java

@RequiredArgsConstructor
@Controller
public class MainController {

    private final MailComponents mailComponents;

    @RequestMapping("/")
    public String index() {
        String email = "kdew0308@naver.com";
        String subject = "안녕하세요. 김이슬입니다. ";
        String text = "<p>안녕하세요. </p><p>반갑습니다.</p>";

        mailComponents.sendMail(email,subject,text);

        return "index";
    }
}

9. 전송된 메일을 통한 계정 활성화

  1. Member.java 안에 private boolean emailAuthYn;private String emailAuthKey; 추가
  • emailAuthKey : 회원가입할 때 key를 만들어서 이 key를 이메일로 전송해주고 보내준 이메일 링크를 타고 들어옴
  • emailAuthYn : key가 맞으면 true로 바꿔줌!
  1. randomUUID 만들기
  • member.setEmailAuthYn(false); : 회원가입을 하면 처음에는 false(인증을 안했으니까)
  • member.setEmailAuthKey(UUID.randomUUID().toString()); : 임의의 값으로 key 만들기

MemberServiceImpl.java

@RequiredArgsConstructor
@Service
public class MemberServiceImpl implements MemberService {
    private final MemberRepository memberRepository;
    private final MailComponents mailComponents; // 메일을 보내기 위한

    /**
     * 회원 가입
     */
    @Override
    public boolean register(MemberInput parameter) {
        // 중복된 아이디가 있는지
        Optional<Member> optionalMember = memberRepository.findById(parameter.getUserId());
        if (optionalMember.isPresent()) {
            // 현재 userId에 해당하는 데이터가 존재한다면
            return  false;
        }
        
        String uuid = UUID.randomUUID().toString();

        // 회원가입 완료
        Member member = new Member();
        member.setUserId(parameter.getUserId());
        member.setPassword(parameter.getPassword());
        member.setPhone(parameter.getPhone());
        member.setUserName(parameter.getUserName());
        member.setRegDt(LocalDateTime.now());
        member.setEmailAuthYn(false);
        member.setEmailAuthKey(uuid);
        memberRepository.save(member);
        
        String email = parameter.getUserId();
        String subject = "dewlms 사이트 가입을 축하드립니다. ";
        String text = "<p>dewlms 사이트 가입을 축하드립니다. <p><p>아래 링크를 클릭하셔서 가입을 완료 하세요.</p>"
                + "<div><a href='http://localhost:8080.member/email-auth?id=" + uuid + "'> 가입완료 </a></div>";
        
        mailComponents.sendMail(email,subject,text);

        return true;
    }
}



  • http://www.naver.com/news/list.do?id=123
    • http : 프로토콜
    • www : 도메인 또는 ip, 서버의 주소
    • ?뒤에 나오는 id=123 : 파라미터 또는 쿼리스트링
      • 여러개 사용하고싶으면 &사용 ex) id=123&id=456

9-1) 간단하게 코드 다듬기!

// 회원가입 완료
        Member member = new Member();
        member.setUserId(parameter.getUserId());
        member.setPassword(parameter.getPassword());
        member.setPhone(parameter.getPhone());
        member.setUserName(parameter.getUserName());
        member.setRegDt(LocalDateTime.now());
        member.setEmailAuthYn(false);
        member.setEmailAuthKey(uuid);

Member.java에 @AllArgsConstructor,@NoArgsConstructor, @Builder 추가해주고
윗 부분을

// 회원가입 완료
Member member = Member.builder()
                .userId(parameter.getUserId())
                .userName(parameter.getUserName())
                .phone(parameter.getPhone())
                .password(parameter.getPassword())
                .regDt(LocalDateTime.now())
                .emailAuthYn(false)
                .emailAuthKey(uuid)
                .build();

이렇게 수정

에러 발생

해결

"<div><a target='_blank' href='http://localhost:8080/member/email-auth?id=" + uuid + "'>
이렇게 수정

9-2) 전체 코드

MemberService.java

public interface MemberService {

    boolean register(MemberInput parameter);

    /**
     * uuid에 해당하는 계정을 활성화 함
     */
    boolean emailAuth(String uuid);
}

MemberServiceImpl.java

@RequiredArgsConstructor
@Service
public class MemberServiceImpl implements MemberService {
    private final MemberRepository memberRepository;
    private final MailComponents mailComponents; // 메일을 보내기 위한

    /**
     * 회원 가입
     */
    @Override
    public boolean register(MemberInput parameter) {
        // 중복된 아이디가 있는지
        Optional<Member> optionalMember = memberRepository.findById(parameter.getUserId());
        if (optionalMember.isPresent()) {
            // 현재 userId에 해당하는 데이터가 존재한다면
            return  false;
        }

        String uuid = UUID.randomUUID().toString();

        // 회원가입 완료
        Member member = Member.builder()
                .userId(parameter.getUserId())
                .userName(parameter.getUserName())
                .phone(parameter.getPhone())
                .password(parameter.getPassword())
                .regDt(LocalDateTime.now())
                .emailAuthYn(false)
                .emailAuthKey(uuid)
                .build();
        memberRepository.save(member);

        String email = parameter.getUserId();
        String subject = "dewlms 사이트 가입을 축하드립니다. ";
        String text = "<p>dewlms 사이트 가입을 축하드립니다. <p><p>아래 링크를 클릭하셔서 가입을 완료 하세요.</p>"
                + "<div><a target='_blank' href='http://localhost:8080/member/email-auth?id=" + uuid + "'> 가입완료 </a></div>";

        mailComponents.sendMail(email,subject,text);

        return true;
    }

    // 계정 활성화
    @Override
    public boolean emailAuth(String uuid) {

        Optional<Member> optionalMember = memberRepository.findByEmailAuthKey(uuid);
        if(!optionalMember.isPresent()) {
            return false;
        }

        Member member = optionalMember.get(); // 있다면 멤버 정보 가져옴!
        member.setEmailAuthYn(true);
        member.setEmailAuthDt(LocalDateTime.now());
        memberRepository.save(member);

        return true;
    }
}

MemberController.java

@RequiredArgsConstructor
@Controller
public class MemberController {

    private final MemberService memberService;

    @GetMapping("/member/register")
    public String register() {

        return "member/register";
    }

    @PostMapping("/member/register")
    public String registerSubmit(Model model, HttpServletRequest request
            , MemberInput parameter) {

        boolean result = memberService.register(parameter);

        model.addAttribute("result",result);

        return "member/register_complete";
    }

    @GetMapping("/member/email-auth")
    public String emailAuth(Model model, HttpServletRequest request) {

        String uuid = request.getParameter("id");
        System.out.println(uuid);

        boolean result = memberService.emailAuth(uuid);
        model.addAttribute("result", result);

        return "member/email_auth";

    }

}

email_auth.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title> 회원 활성화 </title>
</head>
<body>
  <h1>회원 활성화</h1>

  <div th:if="${result eq true}">
      <p>회원님의 계정이 활성화 되었습니다.</p>
  </div>

  <div th:if="${result eq false}">
      <p>회원님의 계정이 활성화에 실패하였습니다.</p>
  </div>

</body>
</html>

Member.java

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
public class Member {
    @Id
    private String userId;

    private String userName;
    private String phone;
    private String password;
    private LocalDateTime regDt; // 회원가입 날짜

    private boolean emailAuthYn;
    private LocalDateTime emailAuthDt; // 이메일 인증 날짜
    private String emailAuthKey;

}

MemberRepository.java

public interface MemberRepository extends JpaRepository<Member, String> {

    Optional<Member> findByEmailAuthKey(String emailAuthKey);
}

MailComponents.java

@RequiredArgsConstructor
@Component
public class MailComponents {

    private final JavaMailSender javaMailSender;

    public void sendMailTest() {
        SimpleMailMessage msg = new SimpleMailMessage();
        msg.setTo("leesil1006@naver.com"); // 누구한테 보낼 것인지
        msg.setSubject("안녕하세요!"); // 제목
        msg.setText("안녕하세요 반갑습니다!"); // 내용

        javaMailSender.send(msg);
    }

    public boolean sendMail(String mail, String subject, String text) {
        boolean result = false;
        MimeMessagePreparator msg = new MimeMessagePreparator() {
            @Override
            public void prepare(MimeMessage mimeMessage) throws Exception {
                MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
                mimeMessageHelper.setTo(mail);
                mimeMessageHelper.setSubject(subject);
                mimeMessageHelper.setText(text, true);

            }
        };

        try {
            javaMailSender.send(msg);
            result = true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        // 디테일하게 메일 보내기
        return result;
    }
}

MailConfig.java

@Configuration
public class MailConfig {
    @Bean
    public JavaMailSender javaMailService() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setHost("smtp.gmail.com");
        javaMailSender.setPort(587);
        javaMailSender.setUsername("kdew0308@gmail.com");
        javaMailSender.setPassword("icoyvbtzhcktmrzc");

        //세부사항
        Properties prop = new Properties();
        prop.setProperty("mail.transport.protocol", "smtp");
        prop.setProperty("mail.smtp.auth", "true");
        prop.setProperty("mail.smtp.starttls.enable", "true");
        prop.setProperty("mail.debug", "true");
        javaMailSender.setJavaMailProperties(prop);

        return javaMailSender;
    }

}

0개의 댓글

관련 채용 정보