Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[피오 & 노리] 웹서버 4단계 - 쿠키를 이용한 로그인 구현 #67

Open
wants to merge 4 commits into
base: pio-nori
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/main/java/db/SessionDataBase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package db;

import java.util.HashMap;
import java.util.Map;

public class SessionDataBase {

private static final Map<String, String> SESSIONS = new HashMap<>();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HashMap 을 사용해주신 이유는 무엇인가요?


public static void save(String sessionId, String userId) {
SESSIONS.put(sessionId, userId);
}

public static void remove(String sessionId) {
SESSIONS.remove(sessionId);
}
Comment on lines +10 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드명 👍

}
6 changes: 4 additions & 2 deletions src/main/java/webserver/HttpRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init() 메서드 같은건 필요없죠. 앞으로도 계속 지양해주세요.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BufferedReader 가 상태로 관리되는 이유가 있나요?

this.parameters = parseParameter();
}
Expand All @@ -48,4 +47,7 @@ public String getParameter(String key) {
return parameters.get(key);
}

public String getHeader(String header) {
return headers.get(header);
}
}
26 changes: 24 additions & 2 deletions src/main/java/webserver/HttpResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,32 @@ public HttpResponse(OutputStream out) {
}


public void response302Header() {
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");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 객체가 stream 을 직접 가지고서 응답을 반환하는 것은 도메인을 담당하는 객체가 출력을 하는 것과 동일합니다. 지양해주세요.

dos.writeBytes("Set-Cookie: sessionId=" + cookie + "; Max-Age=-1; path=/");
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
Comment on lines +28 to +30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 올바른 예외처리가 아닙니다. 지양해주세요.

}

public void response302WithCookieHeader(String path, String cookie) {
try {
dos.writeBytes("HTTP/1.1 302 FOUND \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) {
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");
Comment on lines 24 to +47
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

중복되는 코드가 많네요. 재사용을 고려할 필요는 없을까요?

dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
Expand Down
50 changes: 45 additions & 5 deletions src/main/java/webserver/RequestHandler.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package webserver;

import db.DataBase;
import db.SessionDataBase;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
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 {

Expand All @@ -32,21 +36,57 @@ 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"),
httpRequest.getParameter("name"),
httpRequest.getParameter("email")
);
DataBase.addUser(user);
HttpResponse httpResponse = new HttpResponse(out);
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");
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("/index.html", sessionId);
return;
}

if (httpRequest.getPath().equals("/user/logout")) {
Map<String, String> cookies = HttpRequestUtils.parseCookies(
httpRequest.getHeader("Cookie"));
String sessionId = cookies.get("sessionId");
log.debug("sessionId = {}", sessionId);
if (sessionId == null) {
httpResponse.response302Header("/index.html");
return;
}
httpResponse.response302WithExpiredCookieHeader("/index.html", sessionId);
SessionDataBase.remove(sessionId);
Comment on lines +39 to +86
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드가 너무 길죠. 리팩토링 해주세요. depth 2단계는 여기서도 지양해주셔야 합니다.

return;
}

HttpResponse httpResponse = new HttpResponse(out);
httpResponse.writeBody(httpRequest.getPath());
httpResponse.response200Header();
httpResponse.responseBody();
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/webserver/RequestLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
4 changes: 2 additions & 2 deletions webapp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<li><a href="#loginModal" role="button" data-toggle="modal">로그인</a></li>
<li><a href="#registerModal" role="button" data-toggle="modal">회원가입</a></li>
-->
<li><a href="#" role="button">로그아웃</a></li>
<li><a href="/user/logout" role="button">로그아웃</a></li>
<li><a href="#" role="button">개인정보수정</a></li>
</ul>
</div>
Expand Down Expand Up @@ -145,4 +145,4 @@
<script src="js/bootstrap.min.js"></script>
<script src="js/scripts.js"></script>
</body>
</html>
</html>