권한, 게시판(카테고리)를 만들기 이전에 해당 기능들을 이용할 수 있는 계정부터 만들 수 있게 페이지를 생성한다.
1. WEB-INF/jsp/admin 아래 페이지 생성
우선 계정관리 페이지를 하나 만든다
user_management.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>사용자 관리화면</title>
<sec:csrfMetaTags />
<link rel="stylesheet" href="/css/main.css">
</head>
<body>
<header>
<nav>
<div class="menu">
<div class="menu-item"><a href="${pageContext.request.contextPath}/">홈화면으로</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/userList">사용자관리화면</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/roleList">권한관리화면</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/boardList">게시판화면</a></div>
</div>
</nav>
</header>
<main>
<nav>
<ul>
<li><a href="${pageContext.request.contextPath}/admin/userList" id="userList">사용자 목록</a></li>
<li><a href="${pageContext.request.contextPath}/admin/addUserForm" id="addUser">사용자 등록</a></li>
</ul>
</nav>
<section id="content">
<h2>사용자 목록</h2>
<form action="/deleteUser" method="post">
<sec:csrfInput />
<!-- 사용자 목록을 테이블로 표시합니다. -->
<table border="1">
<thead>
<tr>
<th>사용자 ID</th>
<th>이름</th>
<th>관리</th>
</tr>
</thead>
<tbody>
<c:forEach var="user" items="${users}">
<tr>
<td>${user.username}</td>
<td>${user.name}</td>
<td><a href="/admin/modifyUserForm?username=${user.username}">수정</a></td>
</tr>
</c:forEach>
</tbody>
</table>
</form>
</section>
</main>
<script>
</script>
</body>
</html>
레이아웃을 좀 바꾸었는데, 우선 상단에 홈화면/사용자/권한/게시판 관리화면을 놓고
main 에 섹션을 나누어 왼쪽측면은 메뉴, 가운데는 내용을 표시하도록 바꿨다.
그리고 앞으로 만들 사용자목록, 등록 /권한/게시판 관련 a href 링크도 추가해두었음.
사용자 등록및 목록 페이지도 만들어둔다.
사용자등록화면
user_add_form.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>사용자 등록화면</title>
<sec:csrfMetaTags />
<link rel="stylesheet" href="/css/main.css">
</head>
<body>
<header>
<nav>
<div class="menu">
<div class="menu-item"><a href="${pageContext.request.contextPath}/">홈화면으로</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/userList">사용자관리화면</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/roleList">권한관리화면</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/boardList">게시판화면</a></div>
</div>
</nav>
</header>
<main>
<nav>
<ul>
<li><a href="${pageContext.request.contextPath}/admin/userList" id="userList">사용자 목록</a></li>
<li><a href="${pageContext.request.contextPath}/admin/addUserForm" id="addUser">사용자 등록</a></li>
</ul>
</nav>
<section id="content">
<form action="/admin/addUser" method="post">
<sec:csrfInput />
<div>
<label for="username">ID:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div>
<label for="name">이름:</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<button type="submit">등록</button>
</div>
</form>
</section>
</main>
<script>
</script>
</body>
</html>
form 태그로 제출하여 등록하는 일반적인 페이지
사용자 수정화면
user_modify_form.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>사용자 관리화면</title>
<sec:csrfMetaTags />
<link rel="stylesheet" href="/css/main.css">
</head>
<body>
<header>
<nav>
<div class="menu">
<div class="menu-item"><a href="${pageContext.request.contextPath}/">홈화면으로</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/userList">사용자관리화면</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/roleList">권한관리화면</a></div>
<div class="menu-item"><a href="${pageContext.request.contextPath}/admin/boardList">게시판화면</a></div>
</div>
</nav>
</header>
<main>
<nav>
<ul>
<li><a href="${pageContext.request.contextPath}/admin/userList" id="userList">사용자 목록</a></li>
<li><a href="${pageContext.request.contextPath}/admin/addUserForm" id="addUser">사용자 등록</a></li>
</ul>
</nav>
<section id="content">
<form action="/admin/modifyUser" method="post">
<sec:csrfInput />
<div>
<label for="username">ID:</label>
<input type="text" id="username" name="username" value="${user.username}" readonly>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" value="${user.password}" required>
</div>
<div>
<label for="name">이름:</label>
<input type="text" id="name" name="name" value="${user.name}" required>
</div>
<div>
<button type="submit">수정</button>
</div>
</form>
<button id="deleteUser" value="${user.username}">사용자 삭제</button>
</section>
</main>
<script>
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '${_csrf.token}'
}
});
$('#deleteUser').click(function(){
let username = $(this).val();
if(confirm('삭제 하시겠습니까?')){
$.ajax({
url: '/admin/deleteUser',
method: 'POST',
data: { username, username },
success: function(data){
console.log(data);
window.location.href = '/admin/userList'
}, error: function(err){
console.log(err);
}
});
} else {
console.log("취소");
}
});
</script>
</body>
</html>
삭제를 한번 막기위해 confirm 함수를 사용하였음.
현재 spring security 를 보면 csrf 를 disable 해두었는데, 앞으로는 이 기능도 풀예정이니 정상적인 post 방식을 사용하기 위해 아래와같은 코드를 집어넣은것을 볼 수 있다.
<sec:csrfInput />
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '${_csrf.token}'
}
});
하나만 있어도 잘 됨.
SecurityConfig.java 에서
// http
// .csrf((auth) -> auth.disable());
위 코드를 이제 주석처리해주자. 앞으로 form 태그 및 POST는 위 토큰을 넣어 정상 처리가 가능하게끔 한다.
(이전의 모든 form 태그들에 위 코드를 추가해야함.)
2. 컨트롤러 추가
admin 관련업무라서 adminController 를 추가하였다.
@Controller
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping("/admin")
public class adminController {
@Autowired
UserService userService;
@Autowired
PostService postService;
@Autowired
SecurityUtil securityUtil;
ModelAndView mav = new ModelAndView();
또한 앞으로 만들 UserService 와 기존의 PostService (카테고리 추가용),
Spring security 를 이용할 securityUtil 을 미리 Autowired 시켜두었다.
GetMapping 을 통해 페이지로 이동 시킬 수 있게 해준다. (위 a href 로 적용해둠)
@GetMapping("/userList")
public ModelAndView userListPage() {
mav.addObject("users", userService.findAllUser());
mav.setViewName("admin/user_management");
return mav;
}
@GetMapping("/addUserForm")
public String addUserForm() {
return "admin/user_add_form";
}
@GetMapping("/modifyUserForm")
public ModelAndView modifyUserForm(HttpServletRequest request) {
String username = request.getParameter("username");
mav.addObject("user", userService.getUserInfo(username));
mav.setViewName("admin/user_modify_form");
return mav;
}
PostMapping 으로 로직을 구현해서 처리한다.
@PostMapping("/addUser")
public String registerUser(@ModelAttribute User user) {
userService.addUser(user);
return "redirect:/admin/userList";
}
(userService 는 이후 한번에 기록 예정)
유저 등록
@PostMapping("/modifyUser")
public String modifyUser(@ModelAttribute User user){
userService.modifyUserInfo(user);
return "redirect:/admin/userList";
}
@PostMapping("/deleteUser")
public ResponseEntity<String> deleteUser(HttpServletRequest request){
String username = request.getParameter("username");
userService.deleteUser(username);
return ResponseEntity.ok("");
}
3. 서비스 추가
@Service
public class UserService {
@Autowired
UserDao userDao;
@Autowired
PasswordEncoder passwordEncoder;
public void addUser(User user) {
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
userDao.insertUser(user);
}
유저등록시 PAsswordEncoder 를 통해 비밀번호 암호화를 한다. (SpringSecurity)
public List<User> findAllUser() {
return userDao.selectAllUser();
}
public User getUserInfo(String username) {
return userDao.selectUserInfo(username);
}
public void modifyUserInfo(User user) {
String password = user.getPassword();
user.setPassword(passwordEncoder.encode(password));
userDao.modifyUserInfo(user);
}
@Transactional
public void deleteUser(String username) {
userDao.deleteRoleUserByUsername(username);
userDao.deleteUser(username);
}
4. Dao 만들기
public void insertUser(User user) {
sqlSession.insert("UserMapper.insertUser", user);
}
public List<User> selectAllUser() {
return sqlSession.selectList("UserMapper.selectAllUser");
}
public List<User> selectUserByRoleId(String roleId) {
return sqlSession.selectList("UserMapper.selectUserByRoleId", Integer.parseInt(roleId));
}
public User selectUserInfo(String username) {
return sqlSession.selectOne("UserMapper.selectUserInfo", username);
}
public void deleteUser(String username) {
sqlSession.delete("UserMapper.deleteUser", username);
}
public void modifyUserInfo(User user) {
sqlSession.update("UserMapper.modifyUserInfo", user);
}
5. XML SQL Query작성
mapper-user.xml 만들어서
<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="UserMapper">
<select id="selectByUsername" parameterType="String" resultType="com.example.post.model.User">
SELECT * FROM USER1 WHERE username = #{username}
</select>
<insert id="insertUser" parameterType="com.example.post.model.User">
INSERT INTO USER1 (username, password, name) values (#{username}, #{password}, #{name})
</insert>
<select id="selectAllUser" resultType="com.example.post.model.User">
SELECT * FROM USER1;
</select>
<insert id="insertRoleByUsername" parameterType="map">
INSERT INTO role_user1 (username, roleId) VALUES (#{username}, #{roleId})
</insert>
<select id="selectUserByRoleId" parameterType="int" resultType="com.example.post.model.User">
select u.username, u.name, c.roleId from user1 u
left join ( select * from role_user1 where roleId = #{roleId} ) c on u.username = c.username;
</select>
<select id="selectUserInfo" parameterType="String" resultType="com.example.post.model.User">
SELECT * FROM user1 WHERE username = #{username}
</select>
<update id="modifyUserInfo" parameterType="com.example.post.model.User">
UPdate USER1 SET password = #{password}, name = #{name} WHERE username = #{username}
</update>
<delete id="deleteUser" parameterType="String">
DELETE FROM user1 WHERE username = #{username}
</delete>
</mapper>
작성해준다.
이러면 우선 User 등록은 끝