스프링 부트 회원가입 - seupeuling buteu hoewongaib

점프 투 스프링부트 0장 들어가기 전에 0-01 머리말 0-02 저자소개 0-03 주요변경이력 0-04 이 책을 읽기 전에 1장 스프링부트 개발 준비! 1-01 필자가 생각하는 스프링부트란? 1-02 자바 설치하기 1-03 스프링부트 개발 환경 준비하기 1-04 스프링부트 맛보기 1-05 스프링부트 도구 설치하기 2장 스프링부트의 기본 요소 익히기! 2-01 스프링부트 프로젝트의 구조 2-02 컨트롤러 2-03 JPA 2-04 엔티티 2-05 리포지터리 2-06 도메인 별로 분류하기 2-07 질문 목록과 템플릿 2-08 ROOT URL 2-09 서비스 2-10 질문 상세 2-11 답변 등록 2-12 스태틱 디렉터리와 스타일시트 2-13 부트스트랩 2-14 템플릿 상속 2-15 질문 등록과 폼 2-16 공통 템플릿 3장 SBB 서비스 개발! 3-01 내비게이션바 3-02 페이징 3-03 게시물에 일련번호 추가하기 3-04 답변 개수 표시 3-05 스프링 시큐리티 3-06 회원가입 3-07 로그인과 로그아웃 3-08 엔티티 변경 3-09 글쓴이 표시 3-10 수정과 삭제 3-11 추천 3-12 앵커 3-13 마크다운 3-14 검색 3-15 SBB 추가 기능 4장 세상에 선보이는 SBB 서비스! 4-01 서버 4-02 AWS 라이트세일 4-03 서버 접속 설정 4-04 서버 접속 프로그램 4-05 SBB 오픈 4-06 서버 스크립트 4-07 개발과 서버 환경 분리 4-08 Nginx 4-09 로깅 4-10 도메인 4-11 SSL 4-12 PostgreSQL A. 부록 A-01 인텔리제이 사용하기 A-02 AWS 라이트세일 사용 취소 A-03 댓글 (삭제예정) B. 마치며

Backend 처리

DB준비

테이블 생성

CREATE TABLE MEMBERS( ID VARCHAR(50) PRIMARY KEY , PWD VARCHAR(50), NAME VARCHAR(50), EMAIL VARCHAR(50), AUTH INTEGER );

테이블을 다음과 같이 생성한다.

테스트용 계정 추가

INSERT INTO MEMBERS VALUES ('admin', 'admin', 'admin', '', 1);

로그인 테스트를 위해 테스트 계정을 생성해준다.

MemberDto 작성

DB의 형식과 동일하게 DTO를 작성해준다.

// MemberDto import lombok.Getter; @Getter public class MemberDto { private String id; private String pwd; private String name; private String email; private int auth; public MemberDto() { } public MemberDto(String id, String pwd, String name, String email, int auth) { this.id = id; this.pwd = pwd; this.name = name; this.email = email; this.auth = auth; } public void setId(String id) { this.id = id; } public void setPwd(String pwd) { this.pwd = pwd; } public void setName(String name) { this.name = name; } public void setEmail(String email) { this.email = email; } public void setAuth(int auth) { this.auth = auth; } @Override public String toString() { return "id='" + id + '\'' + ", pwd='" + pwd + '\'' + ", name='" + name + '\'' + ", email='" + email + '\'' + ", auth=" + auth; } }

mapper.xml 및 DAO 준비

mapper.xml

MyBatis를 사용하기 위해 다음과 같이 SQL 쿼리문을 작성해주었다.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "//mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.hwangduil.springbootbackend.dao.MemberDao"> <!-- 아아디 중복 확인 --> <select id="getId" parameterType="com.hwangduil.springbootbackend.dto.MemberDto" resultType="java.lang.Integer"> SELECT IFNULL(COUNT(*), 0) FROM MEMBERS WHERE ID = #{id} </select> <!-- 회원 가입 --> <insert id="addMember" parameterType="com.hwangduil.springbootbackend.dto.MemberDto"> INSERT INTO MEMBERS(ID, PWD, NAME, EMAIL, AUTH) VALUES (#{id}, #{pwd}, #{name}, #{email}, 3) </insert> <!-- 로그인 --> <select id="login" parameterType="com.hwangduil.springbootbackend.dto.MemberDto" resultType="com.hwangduil.springbootbackend.dto.MemberDto"> SELECT ID, NAME, EMAIL, AUTH FROM MEMBERS WHERE ID = #{id} AND PWD = #{pwd} </select> </mapper>

MemberDao

package com.hwangduil.springbootbackend.dao; import com.hwangduil.springbootbackend.dto.MemberDto; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface MemberDao { int getId(MemberDto dto); int addMember(MemberDto dto); MemberDto login(MemberDto dto); }

스프링부트에서 DAO는 인터페이스로 작성하고 @Mapper를 통해 mapper.xml의 id를 찾아간다.

아이디 중복검사는 DB를 체크해서 아이디가 존재하면 숫자가 카운트되며 중복되는 아이디가 없을 때 0을 반환한다.
회원가입은 MemberDto를 받아서 추가되는 경우 숫자가 카운트된다.
로그인은 MemberDto를 받아서 MemberDto를 반환해주는데, 이는 프론트엔드단에서 세션을 위해 객체형태로 반환해주는 것이다.

Service 및 Controller

MemberService

import com.hwangduil.springbootbackend.dao.MemberDao; import com.hwangduil.springbootbackend.dto.MemberDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional @RequiredArgsConstructor public class MemberService { private final MemberDao dao; public boolean getId(MemberDto dto) { int n = dao.getId(dto); return n > 0; } public boolean addMember(MemberDto dto) { int n = dao.addMember(dto); return n > 0; } public MemberDto login(MemberDto dto) { return dao.login(dto); } }

우선 getId는 아이디가 중복되는 경우 true를 반환하며 그렇지 않은 경우 false를 반환할 것이다.

addMember는 회원으로 등록되었을 때 true를, 어떤 이유로 인해 등록되지 않은 경우 false를 반환한다.

login은 DB로부터 로그인한 유저의 모든 정보를 가져올 것이기 때문에 MemberDto 형태를 반환형으로 지정해주었다.

MemberController

import com.hwangduil.springbootbackend.dto.MemberDto; import com.hwangduil.springbootbackend.service.MemberService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController @RequiredArgsConstructor public class MemberController { public final Logger logger = LoggerFactory.getLogger(MemberController.class); private final MemberService service; @PostMapping("/getId") public String getId(MemberDto dto) { logger.info("MemberController getId()"); boolean b = service.getId(dto); if(b) { return "no"; } return "ok"; } @PostMapping("/addMember") public String addMember(MemberDto dto) { logger.info("MemberController addMember()"); boolean b = service.addMember(dto); logger.info(dto.toString()); if(b) { return "ok"; } return "no"; } @PostMapping("/login") public MemberDto login(MemberDto dto) { logger.info("MemberController login()"); return service.login(dto); } }

각각은 중요한 정보가 오고가므로 PostMapping 처리 해준다.

getId는 서비스에서의 getId로부터 받아온 값에 대해 true인 경우 아이디가 중복되므로 "no"를 리턴해주도록 했다.

addMember도 마찬가지로 회원가입이 완료되어 카운트 된 숫자가 0보다 클 경우 true를 반환한다. true일 때 회원가입이 완료되므로 "ok"를 리턴한다.

login은 로그인한 정보를 세션에 객체로 저장해두기 위해 MemberDto를 반환하여 프론트엔드단까지 가져간다.

Frontend 처리

index.html

처음으로 로딩되는 페이지이다. 여기서 바로 로그인 페이지로 넘어가도록 자바스크립트로 처리해주었다.

<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>index</title> </head> <body> <script type="text/javascript"> location.href="./auth/login.html"; </script> </body> </html>

회원가입

<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <title>회원가입</title> <style> #app { margin: auto; margin-top: 60px; width: 60%; border: 3px solid #8ac007; padding: 10px; } table, th, td { border: 1px solid black; } p { font-size: 8px; } </style> </head> <body> <h2>회원 가입</h2> <div id="app"> <!-- <form id="frm" action="/addMember" method="post"> --> <table> <tr> <td>아이디</td> <td> <input type="text" id="userid" placeholder="아이디" size="20" /> <p id="idcheck"></p> <button type="button" id="idCheckBtn">중복확인</button> </td> </tr> <tr> <td>사용할 아이디</td> <td> <input type="text" id="id" name="id" size="20" readonly /> </td> </tr> <tr> <td>비밀번호</td> <td> <input type="text" id="pwd" name="pwd" placeholder="비밀번호" size="20" /> </td> </tr> <tr> <td>이름</td> <td> <input type="text" id="name" name="name" placeholder="이름" size="20" /> </td> </tr> <tr> <td>이메일</td> <td> <input type="text" id="email" name="email" placeholder="이메일 주소" size="20" /> </td> </tr> <tr> <td colspan="2"> <button type="button" id="account">회원가입</button> </td> </tr> </table> <!-- </form> --> </div>

기본적인 형식은 위와 같다. form 태그를 사용하지 않았으며 jQuery를 사용해서 AJAX로 처리해줄 것이다.

<script type="text/javascript"> $(document).ready(function() { // 아이디 중복 검사에 대한 로직이다. `getId`에 입력받은 아이디를 JSON 형식으로 POST 요청을 통해 넘겨준다. // 이를 통해 서버단으로부터 전달받은 내용(`res`)가 각각 어떤 메시지를 리턴해주는가에 따른 작업을 처리한다. $("#idCheckBtn").click(function() { $.ajax({ url: "//localhost:3000/getId", type: "POST", data: { "id": $("#userid").val() }, success: function(res) { // alert('success') if(res.trim() == 'ok') { $("#idcheck").html("사용 가능한 아이디입니다."); $("#id").val($("#userid").val()); } else { $("#idcheck").html("사용할 수 없는 아이디입니다."); $("#userid").val(""); $("#userid").focus(); } }, error: function() { alert('error') } }); }); // 가입버튼을 클릭했을 때 처리해줄 내용 // addMember에 POST로 요청을 보낸다. 이 때 보낼 정보는 data로 지정된 JSON 형식의 자바스크립트 객체이다. $("#account").click(function() { $.ajax({ url: "//localhost:3000/addMember", type: "POST", data: { "id": $("#id").val(), "pwd": $("#pwd").val(), "name": $("#name").val(), "email": $("#email").val(), "auth": 1 }, // 마찬가지로 리턴받은 메시지(res)의 결과에 따라 처리해준다. success: function(res) { if(res.trim() == 'ok') { console.log(res); alert("가입되었습니다!"); // location.href="login.html"; } else { alert("가입되지 않았습니다!"); $("#userid").val(""); $("#pwd").val(""); $("#name").val(""); $("#email").val(""); } } }); }); // 아래는 넘겨줄 데이터가 많을 때 form 태그에 아이디를 부여해서 serialize() 메소드로 한번에 데이터를 넘겨주는 방법이다. /* $("#account").on("click", function() { let params = $("#frm").serialize(); if($("#id").val() === "") { $("#idcheck").html("유효한 아이디가 아닙니다."); } $.ajax({ url: "//localhost:3000/addMember", type: "POST", data: params, success: function(res) { if(res.trim() == 'ok') { console.log(res); alert("가입되었습니다!"); // location.href="login.html"; } else { alert("가입되지 않았습니다!"); $("#userid").val(""); $("#pwd").val(""); $("#name").val(""); $("#email").val(""); } } }); }); */ }); </script> </body> </html>

로그인

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <title>로그인</title> <style> #app { margin: auto; margin-top: 60px; width: 60%; border: 3px solid #8ac007; padding: 10px; } table, th, td { border: 1px solid black; } </style> </head> <body> <h2>Login</h2> <div id="app"> <table> <tr> <td>아이디</td> <td> <input type="text" id="id" placeholder="아이디" size="20" /> </td> </tr> <tr> <td>비밀번호</td> <td> <input type="text" id="pwd" placeholder="비밀번호" size="20" /> </td> </tr> <tr> <td colspan="2"> <button type="button" id="login">로그인</button> <a href="account.html">회원가입</a> </td> </tr> </table> </div> <script> // 로그인시 입력한 아이디와 비밀번호를 넘겨준다. // 서버단의 로그인 함수가 MemberDto를 반환하기 때문에 프론트엔드단에서 JSON 형태로 넘어온다. // 아무것도 입력하지 않으면 JSON의 각 Key에 대한 Value가 비어있을 것이기 때문에 조건식으로 검사해준다. // 로그인이 처리되어 정상적으로 넘어왔다면 sessionStorage에 로그인 정보를 저장해서 다른 페이지로 넘겨줄 것이다. $(document).ready(function() { $("#login").click(function() { $.ajax({ url: "//localhost:3000/login", type: "POST", data: { id: $("#id").val(), pwd: $("#pwd").val() }, success: function(json) { // alert('success'); // alert(JSON.stringify(json)); if(json === "") { alert("아이디 또는 비밀번호를 확인하세요."); $("#id").val(""); $("#pwd").val(""); } else { // 로그인 정보를 세션에 저장 sessionStorage.setItem("login", JSON.stringify(json)); alert(`${json.name}님 환영합니다!`); location.href = "../boards/boards.html"; } }, error: function() { alert('error'); } }); }); }); </script> </body> </html>

Toplist

최신 우편물

태그