로그인 구현

심야·2023년 9월 4일
0

웹 개발

목록 보기
42/46
post-thumbnail
post-custom-banner

모의해킹에 사용할 게시판 로그인 구현


login.js

로그인을 요청하면 login.js의 form.addEventlistener() 함수가 호출된다.
fetch 함수로 loginprocess 컨트롤러에 계정 정보를 전달한다.

const form = document.getElementById("login-form");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    const formData = new FormData(form);
    const username = formData.get("user_id");
    const password = formData.get("user_pw");

    fetch("/hackthebox/loginprocess", {
        method: "POST",
        headers: [["Content-Type", "application/json; charset=utf-8"]],
        body: JSON.stringify({
            user_id: username,
            user_pw: password,
        }),
    })
        .then((response) => {
            if (!response.ok) {
                throw new Error("Network response was not ok");
            }
            return response.json();
        })
        .then((result) => {
            if (result.login === "success") {
                alert("로그인에 성공했습니다.");
                location.href = "/hackthebox/community";
            } else if (result.login === "fail") {
                alert("로그인에 실패했습니다. 아이디 또는 패스워드를 확인해주세요.");
                location.href = "/hackthebox/api/login.jsp";
            }
        })
        .catch((error) => {
            console.error(error);
            alert("로그인 중 오류가 발생했습니다. 다시 시도해주세요.");
        });
});

UserLoginController

회원가입하면 로그인도 함께 요청한다. singupDTO 값이 null이면 로그인 파라미터 데이터를 userId, userPwd 변수에 저장한다. 그렇지 않다면 회원가입 파라미터 데이터를 저장한다.

@WebServlet("/loginprocess")
public class UserLoginController extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userId;
        String userPwd;
        JSONObject json;

        UserDTO singupDTO = (UserDTO) req.getAttribute("vo"); // 회원가입 DTO

        if (singupDTO != null) {
            // 회원가입 요청 시 받는 파라미터
            userId = singupDTO.getUser_id();
            userPwd = singupDTO.getPassword();
        } else {
	        // JSON parsing
            BufferedReader br = req.getReader();
            StringBuilder sb = new StringBuilder(); // append 하기위해 StringBuilder 사용
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();

            // 로그인 요청 시 받는 파라미터
            json = new JSONObject(sb.toString());
            userId = json.getString("user_id");
            userPwd = json.getString("user_pw");
        }

        UserDTO loginDTO = new UserDTO();
        loginDTO.setUser_id(userId);
        loginDTO.setPassword(userPwd);

UserDAO의 UserSelect 메서드로 아이디와 패스워드를 인증 후, 인증에 성공하면 세션을 생성한다.

        // TODO: username과 password를 검증하는 코드 작성
        UserDAO dao = new UserDAO();
        UserDTO dto = dao.UserSelect(loginDTO);

        if (dto.getUser_id() != null) {
            if (singupDTO != null) {
                // 회원가입 성공
                json = new JSONObject();
                json.put("signup", "success");

                // 세션 생성
                HttpSession session = req.getSession();
                session.setAttribute("UserId", dto.getUser_id());
                session.setAttribute("UserName", dto.getName());
                resp.setContentType("application/json");
                resp.setCharacterEncoding("UTF-8");
                // JSON
                PrintWriter out = resp.getWriter();
                out.print(json.toString());
                out.flush();
            } else {
                // 로그인 성공
                json = new JSONObject();
                json.put("login", "success");

                // 세션 생성
                HttpSession session = req.getSession();
                session.setAttribute("UserId", dto.getUser_id());
                session.setAttribute("UserName", dto.getName());
                // response
                resp.setContentType("application/json");
                resp.setCharacterEncoding("UTF-8");
                // JSON
                PrintWriter out = resp.getWriter();
                out.print(json.toString());
                out.flush();
            }
        } else {
            // 로그인 실패
            json = new JSONObject();
            json.put("login", "fail");

            // JSON response
            resp.setContentType("application/json");
            resp.setCharacterEncoding("UTF-8");
            PrintWriter out = resp.getWriter();
            out.print(json.toString());
            out.flush();
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("/hackthebox/login");
    }
}

UserSelect

UserDAO의 UserSelect 메소드에서 로그인을 처리한다. SQL 인젝션을 대응하기 위해 prepareStatement를 적용했다.

    public UserDTO UserSelect(UserDTO dto) {
        UserDTO result = new UserDTO();
        String query = "SELECT * FROM users WHERE user_id=? AND password=?";
        conn = driver.getConnect();
        try {
            psmt = conn.prepareStatement(query);
            psmt.setString(1, dto.getUser_id());
            psmt.setString(2, dto.getPassword());
            rs = psmt.executeQuery();
            
            if (rs.next()) {
                result.setUser_id(rs.getString("user_id"));
                result.setName(rs.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.dbClose(rs, stmt, conn);
        }
        return result;
    }

UserLogoutController

로그아웃을 요청하면 세션의 모든 속성을 삭제한 뒤, 인덱스 페이지로 이동한다.

@WebServlet("/logout")
public class UserLogoutController extends HttpServlet {
   @Override
   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       HttpSession session = req.getSession();

       // 모든 속성 한꺼번에 삭제
       session.invalidate();
       
       // 속성 삭제 후 페이지 이동
       RequestDispatcher requestDispatcher = req.getRequestDispatcher("index.jsp");
       requestDispatcher.forward(req, resp);
   }
}

출처

https://github.com/simyat/Vulnerable-Board-Web-Application

profile
하루하루 성실하게, 인생 전체는 되는대로.
post-custom-banner

0개의 댓글