다음으로 글 작성을 회원만 할 수 있게끔 만들어주자.
기존의 글 작성 기능을 담당하던 코드들에 회원이 로그인 했을 때 접근할 수 있게끔 해야된다.
@WebServlet("/article/write")
public class ArticleWriteServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
HttpSession session = request.getSession();
if (session.getAttribute("loginedMemberId") == null) {
response.getWriter().append(
String.format("<script>alert('로그인 하고 이용해'); location.replace('../member/login');</script>"));
return;
}
request.getRequestDispatcher("/jsp/article/write.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
우선은 articleWrite의 코드부터 고쳤다. 로그인 하지 않으면 글 작성버튼을 누를 수 없게 알림창 띄우고 로그인 창으로 넘어가게끔.
잘 작동한다!
로그인상태일 때는 글 작성으로 넘어가는가도 확인해보면 잘 넘어간다.
@WebServlet("/article/dowrite")
public class ArticleDoWriteServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// DB 연결
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("클래스를 찾을 수 없습니다.");
e.printStackTrace();
}
String url = "jdbc:mysql://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
String user = "root";
String password = "1234";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
HttpSession session = request.getSession();
String title = request.getParameter("title");
String body = request.getParameter("content");
int loginedMemberId = (int) session.getAttribute("loginedMemberId");
SecSql sql = SecSql.from("INSERT INTO article");
sql.append("SET regDate = NOW(),");
sql.append("updateDate = NOW(),");
sql.append("title = ?,", title);
sql.append("`body`= ?,", body);
sql.append("memberId= ?,", loginedMemberId);
int id = DBUtil.insert(conn, sql);
response.getWriter().append(String.format(
"<script>alert('%d번 글이 작성되었습니다.'); location.replace('detail?id=%d');</script>", id, id));
} catch (SQLException e) {
System.out.println("SQL 에러: " + e.getMessage());
response.getWriter().append("<script>alert('글 작성에 실패했습니다.'); history.back();</script>");
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
다음으론 실제 글 작성시 글쓴이의 아이디가 실제 DB에 저장될 수 있도록 하드코딩을 지우고 session을 이용해서 넘겼다.
화면에 작성자가 나오게끔 만들어주지 않았으니 화면도 수정하자.
<div>
작성자 :
<%=articleRow.get("memberId")%>
</div>
detail JSP에 해당 div태그를 넣고 보면.
test2로 로그인 하고 글작성까지 해보면.. 작성자 표시까지 잘 뜬다. 근데 생각해보면 번호가 아니고 이름으로 떴으면 좋겠다.
이름을 가져오려면 데이터베이스의 테이블을 병합할 필요가 있다.
detail 서블릿에 이너조인을 해서 member 테이블의 이름을 뽑아와야된다.
SecSql sql = SecSql.from("SELECT a.*, m.name");
sql.append("FROM article AS a");
sql.append("INNER JOIN `member` AS m");
sql.append("ON a.memberId = m.id");
sql.append("WHERE id = ?", id);
해당 서블릿의 쿼리를 일단 수정해주자.
이렇게 수정했는데 갑자기 디테일 페이지가 뜨지 않아서 좀 당황했다.
잘 보면 WHERE절에 alias를 빼먹었다.
SecSql sql = SecSql.from("SELECT a.*, m.name");
sql.append("FROM article AS a");
sql.append("INNER JOIN `member` AS m");
sql.append("ON a.memberId = m.id");
sql.append("WHERE a.id = ?", id);
추가해주고,
JSP에 memberId를 name으로 고쳐주면
이름까지 잘 나와준다.
삭제시 권한 체크를 해보자.
doDelete 서블릿에
if (session.getAttribute("loginedMemberId") == null) {
response.getWriter().append(
String.format("<script>alert('로그인 하고 이용해'); location.replace('../member/login');</script>"));
return;
}
로그인하지 않았을 때 삭제할 수 없게 기존 코드를 다시 붙혀넣고.
SecSql sql = SecSql.from("SELECT *");
sql.append("FROM article");
sql.append("WHERE id = ?", id);
Map<String, Object> articleRow = DBUtil.selectRow(conn, sql);
int loginedMemberId = (int) session.getAttribute("loginedMemberId");
if (loginedMemberId != (int) articleRow.get("memberId")) {
response.getWriter().append(
String.format("<script>alert('%d번 글에대한 권한 x'); location.replace('list');</script>", id));
return;
}
sql = SecSql.from("DELETE");
sql.append("FROM article");
sql.append("WHERE id = ?", id);
기존에 delete만 있던 쿼리문에 select까지 추가해 게시물과 로그인 되어있는 ID가 동일한지 체크 할 수 있게 만든다.
2번 회원이 로그인 상태고.
1번회원으로 생성된 글을 지우도록 시도해보자.
권한이 없다고 잘 표시된다.
로그인 한 회원이 쓴 글을 삭제해보면 잘 된다.
'Coding History' 카테고리의 다른 글
국비 지원 IT(웹앱개발) 취업반 강의 48일차 (Spring) (1) | 2024.08.12 |
---|---|
국비 지원 IT(웹앱개발) 취업반 강의 47일차 (Spring) (0) | 2024.08.11 |
국비 지원 IT(웹앱개발) 취업반 강의 45일차 2 (HTML, CSS, JS) (0) | 2024.08.07 |
국비 지원 IT(웹앱개발) 취업반 강의 45일차 1 (HTML, CSS, JS) (0) | 2024.08.07 |
국비 지원 IT(웹앱개발) 취업반 강의 44일차 2 (HTML, CSS, JS) (0) | 2024.08.07 |