From 4e5a4ba789039907bf0a7a762ba1dea71d0a0ebd Mon Sep 17 00:00:00 2001 From: Jaehong Choe Date: Tue, 29 Mar 2022 12:40:54 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=BF=A0=ED=82=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로그인이 성공하면 index.html로 이동하고, 로그인이 실패하면 /user/login_failed.html로 이동시킨다. - 아이디와 비밀번호가 같은지를 확인해서 로그인이 성공하면 응답 header의 Set-Cookie 값을 sessionId로 지정해준다. 값은 UUID로 생성한다. --- src/main/java/db/SessionDataBase.java | 13 ++++++++++ src/main/java/webserver/HttpRequest.java | 3 +++ src/main/java/webserver/HttpResponse.java | 20 +++++++++++++++ src/main/java/webserver/RequestHandler.java | 28 ++++++++++++++++++--- 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 src/main/java/db/SessionDataBase.java diff --git a/src/main/java/db/SessionDataBase.java b/src/main/java/db/SessionDataBase.java new file mode 100644 index 00000000..7a6ed7ef --- /dev/null +++ b/src/main/java/db/SessionDataBase.java @@ -0,0 +1,13 @@ +package db; + +import java.util.HashMap; +import java.util.Map; + +public class SessionDataBase { + + private static final Map SESSIONS = new HashMap<>(); + + public static void save(String sessionId, String userId) { + SESSIONS.put(sessionId, userId); + } +} diff --git a/src/main/java/webserver/HttpRequest.java b/src/main/java/webserver/HttpRequest.java index 83b5ad10..ded54cc1 100644 --- a/src/main/java/webserver/HttpRequest.java +++ b/src/main/java/webserver/HttpRequest.java @@ -48,4 +48,7 @@ public String getParameter(String key) { return parameters.get(key); } + public String getHeader(String header) { + return headers.get(header); + } } diff --git a/src/main/java/webserver/HttpResponse.java b/src/main/java/webserver/HttpResponse.java index 28d2978d..476bd70d 100644 --- a/src/main/java/webserver/HttpResponse.java +++ b/src/main/java/webserver/HttpResponse.java @@ -18,6 +18,26 @@ public HttpResponse(OutputStream out) { this.dos = new DataOutputStream(out); } + public void response302WithCookieHeader(String cookie) { + try { + dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); + dos.writeBytes("Location: http://localhost:8080/index.html\r\n"); + dos.writeBytes("Set-Cookie: sessionId=" + cookie + "; path=/"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + public void response302Header(String path) { + try { + dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); + dos.writeBytes("Location: http://localhost:8080/" + path + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } public void response302Header() { try { diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index b7104ab2..81a0c352 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,6 +1,7 @@ package webserver; import db.DataBase; +import db.SessionDataBase; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -8,9 +9,12 @@ import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.UUID; import model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import util.HttpRequestUtils; public class RequestHandler extends Thread { @@ -32,8 +36,9 @@ public void run() { new InputStreamReader(in, StandardCharsets.UTF_8)); HttpRequest httpRequest = new HttpRequest(br); + HttpResponse httpResponse = new HttpResponse(out); - if (httpRequest.getPath().contains("/user/create")) { + if (httpRequest.getPath().equals("/user/create")) { User user = new User( httpRequest.getParameter("userId"), httpRequest.getParameter("password"), @@ -41,12 +46,29 @@ public void run() { httpRequest.getParameter("email") ); DataBase.addUser(user); - HttpResponse httpResponse = new HttpResponse(out); httpResponse.response302Header(); return; } - HttpResponse httpResponse = new HttpResponse(out); + if (httpRequest.getPath().equals("/user/login")) { + User user = DataBase.findUserById(httpRequest.getParameter("userId")); + if (user == null) { + httpResponse.response302Header("user/login_failed.html"); + return; + } + if (!user.getPassword().equals(httpRequest.getParameter("password"))) { + httpResponse.response302Header("user/login_failed.html"); + return; + } + String sessionId = UUID.randomUUID().toString(); + log.debug("return cookie: {}", sessionId); + SessionDataBase.save(sessionId, user.getUserId()); + httpResponse.response302WithCookieHeader(sessionId); + return; + } + + Map cookies = HttpRequestUtils.parseCookies( + httpRequest.getHeader("Cookie")); httpResponse.writeBody(httpRequest.getPath()); httpResponse.response200Header(); httpResponse.responseBody(); From 34d5a016ea1d9e4536ca577ba0cbfd17b84977ae Mon Sep 17 00:00:00 2001 From: nori Date: Wed, 30 Mar 2022 11:56:00 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EC=BF=A0=ED=82=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=9C=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로그아웃 요청이 오면 쿠키를 만료시킨다. --- src/main/java/db/SessionDataBase.java | 4 ++++ src/main/java/webserver/HttpResponse.java | 19 ++++++++++++++++--- src/main/java/webserver/RequestHandler.java | 16 ++++++++++++++-- webapp/index.html | 4 ++-- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/main/java/db/SessionDataBase.java b/src/main/java/db/SessionDataBase.java index 7a6ed7ef..6fab7f03 100644 --- a/src/main/java/db/SessionDataBase.java +++ b/src/main/java/db/SessionDataBase.java @@ -10,4 +10,8 @@ public class SessionDataBase { public static void save(String sessionId, String userId) { SESSIONS.put(sessionId, userId); } + + public static void remove(String sessionId) { + SESSIONS.remove(sessionId); + } } diff --git a/src/main/java/webserver/HttpResponse.java b/src/main/java/webserver/HttpResponse.java index 476bd70d..5bc333f1 100644 --- a/src/main/java/webserver/HttpResponse.java +++ b/src/main/java/webserver/HttpResponse.java @@ -1,12 +1,13 @@ package webserver; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import util.IOUtils; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; + public class HttpResponse { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -18,6 +19,18 @@ public HttpResponse(OutputStream out) { this.dos = new DataOutputStream(out); } + + public void response302WithExpiredCookieHeader(String cookie) { + try { + dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); + dos.writeBytes("Location: http://localhost:8080/index.html\r\n"); + dos.writeBytes("Set-Cookie: sessionId=" + cookie + "; Max-Age=-1; path=/"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + public void response302WithCookieHeader(String cookie) { try { dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 81a0c352..0545f888 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -67,8 +67,20 @@ public void run() { return; } - Map cookies = HttpRequestUtils.parseCookies( - httpRequest.getHeader("Cookie")); + if (httpRequest.getPath().equals("/user/logout")) { + Map cookies = HttpRequestUtils.parseCookies( + httpRequest.getHeader("Cookie")); + String sessionId = cookies.get("sessionId"); + log.debug("sessionId = {}", sessionId); + if (sessionId == null) { + httpResponse.response302Header(); + return; + } + httpResponse.response302WithExpiredCookieHeader(sessionId); + SessionDataBase.remove(sessionId); + return; + } + httpResponse.writeBody(httpRequest.getPath()); httpResponse.response200Header(); httpResponse.responseBody(); diff --git a/webapp/index.html b/webapp/index.html index 1675898a..939884b9 100644 --- a/webapp/index.html +++ b/webapp/index.html @@ -71,7 +71,7 @@
  • 로그인
  • 회원가입
  • --> -
  • 로그아웃
  • +
  • 로그아웃
  • 개인정보수정
  • @@ -145,4 +145,4 @@ - \ No newline at end of file + From 02c22ede3223a00283ba65fd08d148d56bdd088a Mon Sep 17 00:00:00 2001 From: Jaehong Choe Date: Thu, 31 Mar 2022 14:24:38 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20RequestLine=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit requestLine 정보를 ReqeustLine이 파싱하도록 함. --- src/main/java/webserver/HttpRequest.java | 3 +-- src/main/java/webserver/RequestLine.java | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/webserver/HttpRequest.java b/src/main/java/webserver/HttpRequest.java index ded54cc1..63c6fde1 100644 --- a/src/main/java/webserver/HttpRequest.java +++ b/src/main/java/webserver/HttpRequest.java @@ -22,8 +22,7 @@ public HttpRequest(BufferedReader br) throws IOException { private void init() throws IOException { String requestLine = URLDecoder.decode(br.readLine(), StandardCharsets.UTF_8); - String[] requestLineSplit = requestLine.split(" "); - this.requestLine = new RequestLine(requestLineSplit[0], requestLineSplit[1], requestLineSplit[2]); + this.requestLine = new RequestLine(requestLine); this.headers = IOUtils.readRequestHeader(br); this.parameters = parseParameter(); } diff --git a/src/main/java/webserver/RequestLine.java b/src/main/java/webserver/RequestLine.java index 79130f82..92f0754a 100644 --- a/src/main/java/webserver/RequestLine.java +++ b/src/main/java/webserver/RequestLine.java @@ -10,10 +10,11 @@ public class RequestLine { private String path; private String httpVersion; - public RequestLine(String httpMethod, String path, String httpVersion) { - this.httpMethod = httpMethod; - this.path = path; - this.httpVersion = httpVersion; + public RequestLine(String requestLine) { + String[] requestLineSplit = requestLine.split(" "); + this.httpMethod = requestLineSplit[0]; + this.path = requestLineSplit[1]; + this.httpVersion = requestLineSplit[2]; } public String getPath() { From 3ffe560ae04adfc9c57a06336ea44e1c88ab69ef Mon Sep 17 00:00:00 2001 From: Jaehong Choe Date: Thu, 31 Mar 2022 15:14:04 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=EC=A4=91=EB=B3=B5=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=20=EA=B0=80=EC=9E=85=20=EC=B2=98=EB=A6=AC=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=B0=8F=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89?= =?UTF-8?q?=EC=85=98=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=A7=A4=EA=B0=9C?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 중복된 userId로 회원가입 요청이 들어올시, 예외를 발생시킨 후 /user/form.html로 이동시킨다. - HttpResponse클래스의 리다이렉션 메서드의 재활용성을 높이기 위해 location을 매개변수로 받는다. --- src/main/java/webserver/HttpResponse.java | 27 ++++++--------------- src/main/java/webserver/RequestHandler.java | 20 +++++++++------ 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/main/java/webserver/HttpResponse.java b/src/main/java/webserver/HttpResponse.java index 5bc333f1..9565c24e 100644 --- a/src/main/java/webserver/HttpResponse.java +++ b/src/main/java/webserver/HttpResponse.java @@ -1,12 +1,11 @@ package webserver; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import util.IOUtils; - import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import util.IOUtils; public class HttpResponse { @@ -20,10 +19,10 @@ public HttpResponse(OutputStream out) { } - public void response302WithExpiredCookieHeader(String cookie) { + public void response302WithExpiredCookieHeader(String path, String cookie) { try { dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); - dos.writeBytes("Location: http://localhost:8080/index.html\r\n"); + dos.writeBytes("Location: http://localhost:8080" + path + "\r\n"); dos.writeBytes("Set-Cookie: sessionId=" + cookie + "; Max-Age=-1; path=/"); dos.writeBytes("\r\n"); } catch (IOException e) { @@ -31,10 +30,10 @@ public void response302WithExpiredCookieHeader(String cookie) { } } - public void response302WithCookieHeader(String cookie) { + public void response302WithCookieHeader(String path, String cookie) { try { dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); - dos.writeBytes("Location: http://localhost:8080/index.html\r\n"); + dos.writeBytes("Location: http://localhost:8080" + path + "\r\n"); dos.writeBytes("Set-Cookie: sessionId=" + cookie + "; path=/"); dos.writeBytes("\r\n"); } catch (IOException e) { @@ -45,17 +44,7 @@ public void response302WithCookieHeader(String cookie) { public void response302Header(String path) { try { dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); - dos.writeBytes("Location: http://localhost:8080/" + path + "\r\n"); - dos.writeBytes("\r\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - - public void response302Header() { - try { - dos.writeBytes("HTTP/1.1 302 FOUND \r\n"); - dos.writeBytes("Location: http://localhost:8080/index.html\r\n"); + dos.writeBytes("Location: http://localhost:8080" + path + "\r\n"); dos.writeBytes("\r\n"); } catch (IOException e) { log.error(e.getMessage()); diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 0545f888..2e34f981 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -45,25 +45,31 @@ public void run() { httpRequest.getParameter("name"), httpRequest.getParameter("email") ); - DataBase.addUser(user); - httpResponse.response302Header(); + + try { + DataBase.addUser(user); + httpResponse.response302Header("/index.html"); + } catch (IllegalArgumentException e) { + log.debug("exception: {}", e.getMessage()); + httpResponse.response302Header("/user/form.html"); + } return; } if (httpRequest.getPath().equals("/user/login")) { User user = DataBase.findUserById(httpRequest.getParameter("userId")); if (user == null) { - httpResponse.response302Header("user/login_failed.html"); + httpResponse.response302Header("/user/login_failed.html"); return; } if (!user.getPassword().equals(httpRequest.getParameter("password"))) { - httpResponse.response302Header("user/login_failed.html"); + httpResponse.response302Header("/user/login_failed.html"); return; } String sessionId = UUID.randomUUID().toString(); log.debug("return cookie: {}", sessionId); SessionDataBase.save(sessionId, user.getUserId()); - httpResponse.response302WithCookieHeader(sessionId); + httpResponse.response302WithCookieHeader("/index.html", sessionId); return; } @@ -73,10 +79,10 @@ public void run() { String sessionId = cookies.get("sessionId"); log.debug("sessionId = {}", sessionId); if (sessionId == null) { - httpResponse.response302Header(); + httpResponse.response302Header("/index.html"); return; } - httpResponse.response302WithExpiredCookieHeader(sessionId); + httpResponse.response302WithExpiredCookieHeader("/index.html", sessionId); SessionDataBase.remove(sessionId); return; }