UserRequest
package shop.mtcoding.blog.user;
import lombok.Data;
public class UserRequest {
//insert 용도의 dto에는 toEntity 메서드를 만든다
@Data
public static class JoinDTO {
private String username;
private String password;
private String email;
public User toEntity() {
return User.builder()
.username(username)
.password(password)
.email(email)
.build();
}
}
@Data
public static class LoginDTO {
private String username;
private String password;
private String rememberMe; // check되면 on 안되면 null
}
}
UserController
package shop.mtcoding.blog.user;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import shop.mtcoding.blog._core.Resp;
import java.util.Map;
@RequiredArgsConstructor
@Controller
public class UserController {
private final UserService userService;
private final HttpSession session;
@GetMapping("/join-form")
public String joinForm() {
return "user/join-form";
}
@PostMapping("/join")
public String join(UserRequest.JoinDTO joinDTO) {
userService.회원가입(joinDTO);
return "redirect:/login-form";
}
@GetMapping("/check-username-available/{username}")
public @ResponseBody Resp<?> checkUsernameAvailable(@PathVariable("username") String username) {
Map<String, Object> dto = userService.유저네임중복체크(username);
return Resp.ok(dto);
}
@GetMapping("/login-form")
public String loginForm() {
return "user/login-form";
}
@PostMapping("/login")
public String login(UserRequest.LoginDTO loginDTO, HttpServletResponse response) {
User sessionUser = userService.로그인(loginDTO);
session.setAttribute("sessionUser", sessionUser);
if (loginDTO.getRememberMe() == null) {
Cookie cookie = new Cookie("username", null);
cookie.setMaxAge(0); // 즉시 삭제
response.addCookie(cookie);
} else {
Cookie cookie = new Cookie("username", loginDTO.getUsername());
cookie.setMaxAge(60 * 60 * 24 * 7); // cookie 하루동안 유지
response.addCookie(cookie);
}
return "redirect:/";
}
@GetMapping("/logout")
public String logout() {
session.invalidate();
return "redirect:/login-form";
}
}
BoardController
package shop.mtcoding.blog.board;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@RequiredArgsConstructor
@Controller
public class BoardController {
@GetMapping("/")
public String home() {
return "board/list";
}
}
UserService
package shop.mtcoding.blog.user;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.Map;
// 비즈니스 로직, 트랜잭션 처리, DTO 완료
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
@Transactional
public void 회원가입(UserRequest.JoinDTO joinDTO) {
userRepository.save(joinDTO.toEntity());
}
public User 로그인(UserRequest.LoginDTO loginDTO) {
// username,password 검사
User user = userRepository.findByUsername(loginDTO.getUsername());
if (user == null) {
throw new RuntimeException("해당 username이 없습니다");
}
if (!(user.getPassword().equals(loginDTO.getPassword()))) {
throw new RuntimeException("해당 passward가 일치하지 않습니다");
}
// 로그인
return user;
}
public Map<String, Object> 유저네임중복체크(String username) {
User user = userRepository.findByUsername(username);
Map<String, Object> dto = new HashMap<>();
if (user == null) {
dto.put("available", true);
} else {
dto.put("available", false);
}
return dto;
}
}
header
<!DOCTYPE html>
<html lang="en">
<head>
<title>Blog</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
.my-like-heart {
font-size: 24px;
color: gray;
cursor: pointer;
}
.my-like-heart.liked {
color: red;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="/">Metacoding</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
{{#sessionUser}}
<li class="nav-item">
<a class="nav-link" href="/board/save-form">글쓰기</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/user/update-form">회원정보보기</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/logout">로그아웃</a>
</li>
{{/sessionUser}}
{{^sessionUser}}
<li class="nav-item">
<a class="nav-link" href="/join-form">회원가입</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/login-form">로그인</a>
</li>
{{/sessionUser}}
</ul>
</div>
</div>
</nav>
login-form
{{> layout/header}}
<div class="container p-5">
<div class="card">
<div class="card-header"><b>로그인을 해주세요</b></div>
<div class="card-body">
<form action="/login" method="post" enctype="application/x-www-form-urlencoded">
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter username" name="username" id="username">
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="Enter password" name="password"
id="password">
</div>
<!-- ✅ 공개 여부 체크박스 -->
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" name="rememberMe" checked>
<label class="form-check-label" for="isUsernameCheck">
아이디를 기억하겠습니까?
</label>
</div>
<button type="submit" class="btn btn-primary form-control">로그인</button>
</form>
</div>
</div>
</div>
<script>
let rememberUsername = getCookie("username");
if (rememberUsername != null) {
document.querySelector("#username").value = rememberUsername;
}
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
return null; // return 안 하면 undefined
}
</script>
{{> layout/footer}}


Share article