4월 25일(2)

SJY0000·2022년 4월 25일
0

Springboot

목록 보기
23/24

오늘 배운 것

  • 로그인, 회원가입

DB만들기

Mapper

  • Login은 쿼리문이 간단하기 때문에 따로 xml파일을 만들어서 작성하지않고 바로작성한다.
package com.myapp.bbs.dao;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import com.myapp.bbs.model.User;

@Mapper
public interface UserMapper {

	@Insert("insert into player values(#{email}, #{password}, #{name})")
	public int insert(User user);
	
	@Update("update player set password = #{password} where email = #{email}")
	public int update(User user);
	
	@Delete("delete from player where email = #{email}")
	public int delete(String email);
	
	@Select("select * from player")
	public List<User> selectAll();
	
	@Select("select * from player where email = #{email}")
	public User selectByEmail(String email);
}

Service

  • LoginService
package com.myapp.bbs.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.myapp.bbs.dao.UserMapper;
import com.myapp.bbs.model.Login;
import com.myapp.bbs.model.User;

@Service
public class LoginService {

	@Autowired
	private UserMapper userMapper;
	
	// 인증하기 메소드 : 실패할 경우 login객체에 에러메세지 입력됨
	public void authenticate(Login login) {
		// 이메일로 검색해서 유저찾기
		User user = userMapper.selectByEmail(login.getEmail());
		
		if(user == null) {
			login.setError("이메일이 존재하지 않습니다.");
		} else {
			if (!user.getPassword().equals(login.getPassword())) {
				login.setError("패스워드가 틀립니다.");
			} else {
				login.setError(null); // 에러없음 (인증됨)
			}
		}
	}
	
	// 유저 찾기 메소드 : 이메일로 유저찾기
	public User findUserByEmail(String emali) {
		User user = userMapper.selectByEmail(emali);
		return user;
	}
}

Controller

  • UserController
  • 회원가입
package com.myapp.bbs.controller;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.myapp.bbs.dao.UserMapper;
import com.myapp.bbs.model.User;

@Controller
public class UserController {

	@Autowired
	private UserMapper userMapper;
	
	@GetMapping("/register")
	public String getUsersView(@ModelAttribute User user) {	
		return "register";
	}
	
	@PostMapping("/register")
	public String postUser(User user, Model model, HttpSession session, RedirectAttributes attr) {
		// 클라이언트 단 또는 서버 단에서 데이터 유효성 체크를 적용하는 것을 권장한다.
		User duplicatedUser = userMapper.selectByEmail(user.getEmail()); // 이메일이 같은 유저가 있는지 검색
		
		if(duplicatedUser == null) {
			// 이메일이 중복이 아니므로 가입처리
			userMapper.insert(user);
			attr.addFlashAttribute("message", "가입되었습니다.");
			return "redirect:/login";
		} else {
			// 이메일이 중복됬으므로 메세지와 함께 다시 Redirect로 돌아감
			attr.addFlashAttribute("message", "중복된 이메일입니다.");
			return "redirect:/register";
		}
	}
		
}
  • LoginController
  • 로그인
package com.myapp.bbs.controller;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

import com.myapp.bbs.model.Login;
import com.myapp.bbs.model.User;
import com.myapp.bbs.service.LoginService;

@Controller
public class LoginController {
	
	@Autowired
	private LoginService loginService;

	@GetMapping("/login")
	public String getLoginView(@ModelAttribute Login login) {
		return "login";
	}
	
	@PostMapping("/login")
	public String postLogin(Login login, Model model, HttpSession session ) {
		loginService.authenticate(login); // 인증메소드 실행 (실패 시 에러메시지 입력됨)
		
		if (login.getError() != null) { 
			model.addAttribute("message", login.getError());
			return "login";
		} else {
			User user = loginService.findUserByEmail(login.getEmail());
			session.setAttribute("user", user);
			return "redirect:/board/list";
		}
	}
}

View

  • 회원가입(register)페이지
  • minlength, maxlength 메소드로 유효성검사 실시
<html xmlns:th="http://www.thymeleaf.org">
  <head th:replace="fragments/head :: 헤드"></head>
  <style>
    input:invalid:focus {
      /* 유효성검사 통과 못할 시*/
      background-image: linear-gradient(pink, skyblue) !important; /* !important는 가장 우선순위를 높게 설정하여 무조건 실행*/
    }
  </style>
  <body class="g-sidenav-show bg-gray-200">
    <aside th:replace="fragments/aside :: 어사이드"></aside>
    <!-- 메인 컨텐트 시작 -->
    <main class="main-content mt-0">
      <section>
        <div class="page-header min-vh-100">
          <div class="container">
            <div class="row">
              <div class="col-6 d-lg-flex d-none h-100 my-auto pe-0 position-absolute top-0 start-0 text-center justify-content-center flex-column">
                <div
                  class="position-relative bg-gradient-primary h-100 m-3 px-7 border-radius-lg d-flex flex-column justify-content-center"
                  style="background-image: url('../assets/img/illustrations/illustration-signup.jpg'); background-size: cover"
                ></div>
              </div>
              <div class="col-xl-4 col-lg-5 col-md-7 d-flex flex-column ms-auto me-auto ms-lg-auto me-lg-5">
                <div class="card card-plain">
                  <div class="card-header">
                    <h4 class="font-weight-bolder">가입하기</h4>
                    <!-- 삼항연산자 ? true : false, 삼항연산자 ?: true(물음표 다음 : 띄우면 안됨)-->
                    <p class="mb-0" th:text="${message} ?: '가입양식을 작성해주세요'"></p>
                  </div>
                  <div class="card-body bg-white">
                    <form role="form" th:action="@{/register}" method="POST" th:object="${user}">
                      <div class="input-group input-group-outline mb-3">
                        <label class="form-label">Name</label>
                        <input type="text" class="form-control" th:field="*{name}" minlength="2" maxlength="5" required />
                      </div>
                      <div class="input-group input-group-outline mb-3">
                        <label class="form-label">Email</label>
                        <input type="email" class="form-control" th:field="*{email}" required />
                      </div>
                      <div class="input-group input-group-outline mb-3">
                        <label class="form-label">Password</label>
                        <input type="password" class="form-control" th:field="*{password}" minlength="4" maxlength="10" required />
                      </div>
                      <div class="form-check form-check-info text-start ps-0">
                        <input class="form-check-input" type="checkbox" value="" id="flexCheckDefault" checked />
                        <label class="form-check-label" for="flexCheckDefault"> I agree the <a href="javascript:;" class="text-dark font-weight-bolder">Terms and Conditions</a> </label>
                      </div>
                      <div class="text-center">
                        <button type="submit" class="btn btn-lg bg-gradient-primary btn-lg w-100 mt-4 mb-0">가입하기</button>
                      </div>
                    </form>
                  </div>
                  <div class="card-footer bg-white text-center pt-0 px-lg-2 px-1">
                    <p class="mb-2 text-sm mx-auto">
                      이미 계정이 있습니까?
                      <a th:href="@{/login}" class="text-primary text-gradient font-weight-bold">로그인</a>
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>
    </main>
    <jslink th:replace="fragments/jslink :: 링크"></jslink>
  </body>
</html>
  • 로그인(Login)페이지
<html xmlns:th="http://www.thymeleaf.org">
  <head th:replace="fragments/head :: 헤드"></head>
  <style>
    input:invalid:focus {
      background-image: linear-gradient(red, blue) !important;
    }
  </style>
  <body class="g-sidenav-show bg-gray-200">
    <aside th:replace="fragments/aside :: 어사이드"></aside>
    <!-- 메인 컨텐츠 시작 -->
    <main class="main-content mt-0">
      <div
        class="page-header align-items-start min-vh-100"
        style="background-image: url('https://images.unsplash.com/photo-1497294815431-9365093b7331?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1950&q=80')"
      >
        <span class="mask bg-gradient-dark opacity-6"></span>
        <div class="container my-auto">
          <div class="row">
            <div class="col-lg-4 col-md-8 col-12 mx-auto">
              <div class="card z-index-0 fadeIn3 fadeInBottom">
                <div class="card-header p-0 position-relative mt-n4 mx-3 z-index-2">
                  <div class="bg-gradient-primary shadow-primary border-radius-lg py-3 pe-1">
                    <h4 class="text-white font-weight-bolder text-center mt-2 mb-0">로그인</h4>
                    <div class="row mt-3">
                      <div class="col-2 text-center ms-auto">
                        <a class="btn btn-link px-3" href="javascript:;">
                          <i class="fa fa-facebook text-white text-lg"></i>
                        </a>
                      </div>
                      <div class="col-2 text-center px-1">
                        <a class="btn btn-link px-3" href="javascript:;">
                          <i class="fa fa-github text-white text-lg"></i>
                        </a>
                      </div>
                      <div class="col-2 text-center me-auto">
                        <a class="btn btn-link px-3" href="javascript:;">
                          <i class="fa fa-google text-white text-lg"></i>
                        </a>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="card-body">
                  <p class="text-primary" th:if="${message}" th:text="${message}"></p>
                  <form role="form" class="text-start" th:action="@{/login}" method="post" th:object="${login}">
                    <div class="input-group input-group-outline my-3">
                      <label class="form-label">Email</label>
                      <input type="email" class="form-control" th:field="*{email}" required />
                    </div>
                    <div class="input-group input-group-outline mb-3">
                      <label class="form-label">Password</label>
                      <input type="password" class="form-control" th:field="*{password}" minlength="4" maxlength="10" required />
                    </div>
                    <div class="form-check form-switch d-flex align-items-center mb-3">
                      <input class="form-check-input" type="checkbox" id="rememberMe" />
                      <label class="form-check-label mb-0 ms-2" for="rememberMe">Remember me</label>
                    </div>
                    <div class="text-center">
                      <button type="submit" class="btn bg-gradient-primary w-100 my-4 mb-2">로그인</button>
                    </div>
                    <p class="mt-4 text-sm text-center">
                      가입한 계정이 없다면?
                      <a th:href="@{/register}" class="text-primary text-gradient font-weight-bold">회원가입</a>
                    </p>
                  </form>
                </div>
              </div>
            </div>
          </div>
        </div>
        <footer class="footer position-absolute bottom-2 py-2 w-100">
          <div class="container">
            <div class="row align-items-center justify-content-lg-between">
              <div class="col-12 col-md-6 my-auto">
                <div class="copyright text-center text-sm text-white text-lg-start">
                  ©
                  <script>
                    document.write(new Date().getFullYear());
                  </script>
                  , made with <i class="fa fa-heart" aria-hidden="true"></i> by
                  <a href="https://www.creative-tim.com" class="font-weight-bold text-white" target="_blank">Creative Tim</a>
                  for a better web.
                </div>
              </div>
              <div class="col-12 col-md-6">
                <ul class="nav nav-footer justify-content-center justify-content-lg-end">
                  <li class="nav-item">
                    <a href="https://www.creative-tim.com" class="nav-link text-white" target="_blank">Creative Tim</a>
                  </li>
                  <li class="nav-item">
                    <a href="https://www.creative-tim.com/presentation" class="nav-link text-white" target="_blank">About Us</a>
                  </li>
                  <li class="nav-item">
                    <a href="https://www.creative-tim.com/blog" class="nav-link text-white" target="_blank">Blog</a>
                  </li>
                  <li class="nav-item">
                    <a href="https://www.creative-tim.com/license" class="nav-link pe-0 text-white" target="_blank">License</a>
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </footer>
      </div>
    </main>
    <jslink th:replace="fragments/jslink :: 링크"></jslink>
  </body>
</html>

회원가입 화면

로그인 화면

0개의 댓글