728x90
반응형
테이블 생성 및 테스트 데이터 추가
MySQL Workbench를 이용해서 회원 정보를 저장할 테이블을 생성하고, 테스트 데이터를 추가합니다.
create table t_user (
user_id varchar(20) not null,
user_password varchar(200) not null,
user_name varchar(20) not null,
user_email varchar(100) not null,
primary key (user_id)
);
insert into t_user (user_id, user_password, user_name, user_email)
values ('gdhong', 'p@ssw0rd', '홍길동', 'hong@test.com'),
('gdshin', 'p@ssw0rd', '신길동', 'shin@test.com'),
('gdgo' , 'p@ssw0rd', '고길동', 'go@test.com' );
UserDto 클래스 생성
로그인한 사용자의 정보를 담을 UserDto 클래스를 생성합니다.
package board.dto;
import lombok.Data;
@Data
public class UserDto {
private String userId;
private String userPassword;
private String userName;
private String userEmail;
}
LoginDto 클래스 생성
로그인 화면에서 사용자가 입력한 아이디와 패스워드를 전달할 LoginDto 클래스를 생성합니다.
package board.dto;
import lombok.Data;
@Data
public class LoginDto {
private String userId;
private String userPassword;
}
LoginController 클래스 생성
로그인 화면에 대한 요청, 로그인 요청, 로그아웃 요청을 처리할 LoginController 클래스를 생성합니다.
package board.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import board.dto.LoginDto;
@Controller
public class LoginController {
// 로그인 화면에 대한 요청
@GetMapping("/login.do")
public String login() throws Exception {
return "login.html";
}
// 로그인 처리에 대한 요청
@PostMapping("/login.do")
public String login(LoginDto loginDto) throws Exception {
// TODO 로그인 로직 구현
return "";
}
}
login 페이지 생성
아이디와 패스워드를 입력받아 서버로 전달하는 페이지를 생성합니다.
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>로그인</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>
<div class="container">
<form action="/login.do" method="post">
<div class="form-group">
<label for="userId">ID</label>
<input type="text" class="form-control" id="userId" name="userId" />
</div>
<div class="mt-2 form-group">
<label for="userPassword">Password</label>
<input type="password" class="form-control" id="userPassword" name="userPassword" />
</div>
<div class="mt-3">
<input type="submit" value="Login" class="btn btn-primary" />
</div>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</body>
</html>
LoginMapper 인터페이스 생성
사용자가 입력한 로그인 정보와 일치하는 사용자 정보를 조회해서 반환하는 메서드를 정의합니다.
package board.mapper;
import org.apache.ibatis.annotations.Mapper;
import board.dto.LoginDto;
import board.dto.UserDto;
@Mapper
public interface LoginMapper {
public UserDto login(LoginDto loginDto) throws Exception;
}
sql-login.xml 파일 생성
로그인 로직을 구현할 쿼리를 저장할 sql-login.xml 파일을 생성합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="board.mapper.LoginMapper">
<select id="login" parameterType="board.dto.LoginDto" resultType="board.dto.UserDto">
select user_id, user_password, user_name, user_email
from t_user
where user_id = #{userId} and user_password = #{userPassword}
</select>
</mapper>
LoginService 인터페이스 생성
package board.service;
import board.dto.LoginDto;
import board.dto.UserDto;
public interface LoginService {
public UserDto login(LoginDto loginDto) throws Exception;
}
LoginServiceImpl 구현 클래스 추가
package board.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import board.dto.LoginDto;
import board.dto.UserDto;
import board.mapper.LoginMapper;
@Service
public class LoginServiceImpl implements LoginService {
@Autowired
private LoginMapper loginMapper;
@Override
public UserDto login(LoginDto loginDto) throws Exception {
return loginMapper.login(loginDto);
}
}
LoginController 컨트롤러 메서드에 로그인 로직 추가
package board.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import board.dto.LoginDto;
import board.dto.UserDto;
import board.service.LoginService;
@Controller
public class LoginController {
@Autowired
private LoginService loginService;
// 로그인 페이지를 반환합니다.
@GetMapping("/login.do")
public String login(HttpSession session) throws Exception {
if (session.getAttribute("user") == null) {
return "login.html";
} else {
return "redirect:/board/openBoardList.do";
}
}
// 일치하는 사용자가 존재하지 않는 경우 메시지와 함께 로그인 페이지로,
// 일치하는 사용자가 존재하는 경우 게시판 페이지로 이동합니다.
@PostMapping("/login.do")
public String login(LoginDto loginDto, HttpSession session) throws Exception {
UserDto userDto = loginService.login(loginDto);
if (userDto == null) {
session.setAttribute("message", "일치하는 정보가 존재하지 않습니다.");
return "redirect:login.do";
} else {
session.setAttribute("user", userDto);
return "redirect:/board/openBoardList.do";
}
}
}
login 페이지에 메시지 처리
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>로그인</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>
<div class="container">
<form action="/login.do" method="post">
<div class="form-group">
<label for="userId">ID</label>
<input type="text" class="form-control" id="userId" name="userId" />
</div>
<div class="mt-2 form-group">
<label for="userPassword">Password</label>
<input type="password" class="form-control" id="userPassword" name="userPassword" />
</div>
<div class="mt-3">
<input type="submit" value="Login" class="btn btn-primary" />
</div>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<script>
// 세션에 로그인 실패 메시지가 존재하는 경우, 메시지를 출력하고 세션에 있는 메시지를 삭제합니다.
let message = "[[${session.message}]]";
if (message) {
alert(message);
document.getElementById("userId").focus();
}
</script>
<th:block th:inline="text">[[${#session.removeAttribute('message')}]]</th:block>
</body>
</html>
게시판 페이지에 로그인 사용자 정보 출력 및 로그인, 로그아웃 버튼 추가
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>게시판</title>
<link rel="stylesheet" th:href="@{/css/style.css}" />
</head>
<body>
<div class="container">
<!-- 로그인 전인 경우 로그인 버튼을 제공 -->
<div th:if="${#strings.isEmpty(session.user)}" style="text-align:right;">
<a href="/login.do" class="btn">login</a>
</div>
<!-- 로그인 성공 시 로그인한 사용자 이름과 로그아웃 버튼을 출력 -->
<div th:unless="${#strings.isEmpty(session.user)}" style="text-align:right;">
<b>[[${session.user.userName}]]</b>님 환영합니다. <a href="/logout.do" class="btn">logout</a>
</div>
<h2>게시판 목록</h2>
<table class="board_list">
<colgroup>
<col width="15%" />
<col width="*" />
<col width="15%" />
<col width="20%" />
</colgroup>
<thead>
<tr>
<th scope="col">글번호</th>
<th scope="col">제목</th>
<th scope="col">조회수</th>
<th scope="col">작성일</th>
</tr>
</thead>
<tbody>
<tr th:if="${#lists.size(list)} > 0" th:each="board : ${list}">
<td th:text="${board.boardIdx}"></td>
<td class="title">
<a href="/board/openBoardDetail.do?boardIdx="
th:attrappend="href=${board.boardIdx}"
th:text="${board.title}"></a>
</td>
<td th:text="${board.hitCnt}"></td>
<td th:text="${board.createdDt}"></td>
</tr>
<tr th:unless="${#lists.size(list)} > 0">
<td colspan="4">조회된 결과가 없습니다.</td>
</tr>
</tbody>
</table>
<a href="/board/openBoardWrite.do" class="btn">글쓰기</a>
</div>
</body>
</html>
LoginController 컨트롤러에 logout 메서드 추가
package board.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import board.dto.LoginDto;
import board.dto.UserDto;
import board.service.LoginService;
@Controller
public class LoginController {
@Autowired
private LoginService loginService;
@GetMapping("/login.do")
public String login(HttpSession session) throws Exception {
if (session.getAttribute("user") == null) {
return "login.html";
} else {
return "redirect:/board/openBoardList.do";
}
}
@PostMapping("/login.do")
public String login(LoginDto loginDto, HttpSession session) throws Exception {
UserDto userDto = loginService.login(loginDto);
if (userDto == null) {
session.setAttribute("message", "일치하는 정보가 존재하지 않습니다.");
return "redirect:login.do";
} else {
session.setAttribute("user", userDto);
return "redirect:/board/openBoardList.do";
}
}
// 세션에 user를 삭제하고, 세션을 무효화한 후 로그인 페이지로 이동합니다.
@GetMapping("/logout.do")
public String logout(HttpSession session) throws Exception {
session.removeAttribute("user");
session.invalidate();
return "redirect:login.do";
}
}
로그인 화면
로그인 실패 시 메시지 출력
로그인 성공 시 게시판 목록으로 이동
LoginCheckInterceptor 클래스 생성
로그인하지 않은 상태에서 게시판으로 접근하는 것을 막기 위해 인터셉터 클래스를 생성합니다.
package board.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 요청 주소에 /board가 포함된 경우, 세션에 user 정보가 존재하는지 체크
// 포함되지 않은 경우 메시지와 함께 login 페이지로 이동
if (request.getRequestURI().indexOf("/board") >= 0 && request.getSession().getAttribute("user") == null) {
request.getSession().setAttribute("message", "로그인 후 사용하실 수 있습니다.");
response.sendRedirect("/login.do");
return false;
} else {
return true;
}
}
}
WebMvcConfiguration 클래스에 생성한 인터셉터 클래스를 등록
package board.configuration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import board.interceptor.LoggerInterceptor;
import board.interceptor.LoginCheckInterceptor;
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggerInterceptor());
registry.addInterceptor(new LoginCheckInterceptor());
}
}
로그인하지 않은 상태에서 게시판으로 접근
728x90
반응형
'수업자료' 카테고리의 다른 글
페이징 기능 추가 (0) | 2023.01.17 |
---|---|
세션으로부터 로그인한 사용자 정보를 가져와서 활용 (0) | 2023.01.13 |
20230110 실습내용 (0) | 2023.01.10 |
20230106 실습내용 (0) | 2023.01.06 |
20230105 실습내용 (0) | 2023.01.05 |
댓글