-
Notifications
You must be signed in to change notification settings - Fork 30
[선을로 & 벅픽] 웹서버 4단계 - 쿠키를 이용한 로그인 구현 #68
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
base: sunullo_bugpigg
Are you sure you want to change the base?
Changes from all commits
a3c1f43
445a1e6
be42f2c
2620c8d
806ec70
f888fd9
046f472
606a131
af20a76
8ff76e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package db; | ||
|
|
||
| import com.google.common.collect.Maps; | ||
| import java.util.Map; | ||
|
|
||
| public class SessionDataBase { | ||
|
|
||
| private static Map<String, String> sessions = Maps.newHashMap(); | ||
|
|
||
| public static void add(String sessionId, String userId) { | ||
| sessions.put(sessionId, userId); | ||
| } | ||
|
|
||
| public static String findBySessionId(String sessionId) { | ||
| return sessions.get(sessionId); | ||
| } | ||
|
|
||
| public static void remove(String sessionId) { | ||
| sessions.remove(sessionId); | ||
| } | ||
|
Comment on lines
+10
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,32 +4,39 @@ | |
|
|
||
| public class Request { | ||
|
|
||
| private String methodType; | ||
| private String requestLine; | ||
| private RequestLine requestLine; | ||
| private Map<String, String> headers; | ||
| private String messageBody; | ||
| private URL url; | ||
|
|
||
| public Request(String requestLine, String messageBody, String methodType, URL url) { | ||
| public Request(RequestLine requestLine, Map<String, String> headers, String messageBody) { | ||
| this.requestLine = requestLine; | ||
| this.headers = headers; | ||
| this.messageBody = messageBody; | ||
| this.methodType = methodType; | ||
| this.url = url; | ||
| } | ||
|
|
||
| public String getMessageBody() { | ||
| return messageBody; | ||
| } | ||
|
|
||
| public String getRequestLine() { | ||
| public RequestLine getRequestLine() { | ||
| return requestLine; | ||
| } | ||
|
|
||
| public URL getURL() { | ||
| return url; | ||
| public Map<String, String> getHeaders() { | ||
| return headers; | ||
| } | ||
|
|
||
| public String getMethodType() { | ||
| return methodType; | ||
| public boolean isGetMethodType() { | ||
| return requestLine.isGetMethodType(); | ||
| } | ||
|
|
||
| public boolean isPostMethodType() { | ||
| return requestLine.isPostMethodType(); | ||
| } | ||
|
Comment on lines
+29
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
|
||
| public URL getUrl() { | ||
| return requestLine.getUrl(); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,5 @@ | ||
| package webserver; | ||
|
|
||
| import db.DataBase; | ||
| import java.io.BufferedReader; | ||
| import java.io.DataOutputStream; | ||
| import java.io.IOException; | ||
|
|
@@ -9,17 +8,8 @@ | |
| import java.io.OutputStream; | ||
| import java.net.Socket; | ||
|
|
||
| import java.net.URLDecoder; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
| import java.util.Map.Entry; | ||
| import model.User; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
| import util.HttpRequestUtils; | ||
| import util.IOUtils; | ||
| import util.RequestLineUtil; | ||
|
|
||
| public class RequestHandler extends Thread { | ||
|
|
||
|
|
@@ -38,39 +28,21 @@ public void run() { | |
| try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { | ||
| BufferedReader br = new BufferedReader(new InputStreamReader(in)); | ||
|
|
||
| Request request = makeRequest(br); | ||
| RequestReader requestReader = new RequestReader(br); | ||
| Request request = requestReader.getRequest(); | ||
|
|
||
| // URL init | ||
| URL url = request.getURL(); | ||
|
|
||
| // user save | ||
| if (request.getMethodType().equals("POST") && url.comparePath("/user/create")) { | ||
| String messageBody = request.getMessageBody(); | ||
| userSave(messageBody, url); | ||
| } | ||
| UserManager userManager = new UserManager(request); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 방식의 구현은 약간 의아하네요~ |
||
| String sessionId = userManager.action(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 왜 |
||
|
|
||
|
Comment on lines
+34
to
36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분의 구현만 봐서는 전체적인 정상 동작이 UserManager 쪽에 전부 이동한 느낌이 드네요. 좋은 방향일까요? |
||
| // Response Message | ||
| DataOutputStream dos = new DataOutputStream(out); | ||
| Response response = new Response(request.getRequestLine(), url); | ||
| Response response = new Response(request.getRequestLine(), sessionId); | ||
| sendResponse(dos, response); | ||
| } catch (IOException e) { | ||
| log.error(e.getMessage()); | ||
| } | ||
| } | ||
|
|
||
| private void userSave(String messageBody, URL url) { | ||
| Map<String, String> userInfo = HttpRequestUtils.parseQueryString(messageBody); | ||
| User user = new User(userInfo.get("userId"), userInfo.get("password"), userInfo.get("name"), | ||
| userInfo.get("email")); | ||
|
|
||
| if (DataBase.findUserById(userInfo.get("userId")) == null) { | ||
| DataBase.addUser(user); | ||
| url.setRedirectHomePage(); | ||
| } else { | ||
| url.setRedirectSignUpPage(); | ||
| } | ||
| } | ||
|
|
||
| private void sendResponse(DataOutputStream dos, Response response) throws IOException { | ||
| response.action(); | ||
|
|
||
|
|
@@ -82,61 +54,4 @@ private void sendResponse(DataOutputStream dos, Response response) throws IOExce | |
| dos.write(body, 0, body.length); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| private Request makeRequest(BufferedReader bufferedReader) throws IOException { | ||
| String requestLine = initRequestLine(bufferedReader); | ||
| Map<String, String> headers = new HashMap<>(); | ||
|
|
||
| initRequestHeaders(bufferedReader, headers); | ||
| outputLog(headers, requestLine); | ||
|
|
||
| URL url = initURL(requestLine, headers); | ||
|
|
||
| String messageBody = ""; | ||
| String methodType = RequestLineUtil.getMethodType(requestLine); | ||
|
|
||
| if (methodType.equals("POST")) { | ||
| messageBody = IOUtils.readData(bufferedReader, | ||
| Integer.parseInt(headers.get("Content-Length:"))); | ||
| log.debug(messageBody); | ||
| } | ||
|
|
||
| return new Request(requestLine, messageBody, methodType, url); | ||
| } | ||
|
|
||
| private void outputLog(Map<String, String> headers, String requestLine) { | ||
| // Request Line Log | ||
| log.debug(requestLine); | ||
| // Request Headers Log | ||
| for (Entry<String, String> entry : headers.entrySet()) { | ||
| log.debug("Request: {} {}", entry.getKey(), entry.getValue()); | ||
| } | ||
| } | ||
|
|
||
| private String initRequestLine(BufferedReader bufferedReader) throws IOException { | ||
| String line; | ||
| if ("".equals(line = bufferedReader.readLine()) || line == null) { | ||
| throw new IllegalArgumentException("Request.bufferedReader.readLine == null 입니다."); | ||
| } | ||
| return line; | ||
| } | ||
|
|
||
| private void initRequestHeaders(BufferedReader bufferedReader, Map<String, String> headers) | ||
| throws IOException { | ||
| String line; | ||
| while (!"".equals(line = bufferedReader.readLine())) { | ||
| if (line == null) { | ||
| throw new IllegalArgumentException("Request.bufferedReader.readLine == null 입니다."); | ||
| } | ||
| String[] splitLine = line.split(" "); | ||
| headers.put(splitLine[0], splitLine[1]); | ||
| } | ||
| } | ||
|
|
||
| private URL initURL(String requestLine, Map<String, String> headers) { | ||
| String decodedUrl = URLDecoder.decode(requestLine, StandardCharsets.UTF_8); | ||
| String host = headers.get("Host:"); | ||
| return new URL(RequestLineUtil.getURL(decodedUrl), host); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package webserver; | ||
|
|
||
| import java.net.URLDecoder; | ||
| import java.nio.charset.StandardCharsets; | ||
|
|
||
| public class RequestLine { | ||
|
|
||
| private String methodType; | ||
| private URL url; | ||
|
|
||
| public RequestLine(String methodType, String url) { | ||
| this.methodType = methodType; | ||
| this.url = makeURL(url); | ||
| } | ||
|
|
||
| private URL makeURL(String url) { | ||
| String decodedUrl = URLDecoder.decode(url, StandardCharsets.UTF_8); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| return new URL(decodedUrl); | ||
| } | ||
|
|
||
| public boolean isGetMethodType() { | ||
| return "GET".equals(methodType); | ||
| } | ||
|
|
||
| public boolean isPostMethodType() { | ||
| return "POST".equals(methodType); | ||
| } | ||
|
|
||
| public URL getUrl() { | ||
| return url; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| package webserver; | ||
|
|
||
| import java.io.BufferedReader; | ||
| import java.io.IOException; | ||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
| import java.util.Map.Entry; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
| import util.IOUtils; | ||
| import util.RequestLineUtil; | ||
|
|
||
| public class RequestReader { | ||
|
|
||
| private static final Logger log = LoggerFactory.getLogger(RequestReader.class); | ||
|
|
||
| private final BufferedReader bufferedReader; | ||
|
|
||
| public RequestReader(BufferedReader bufferedReader) { | ||
| this.bufferedReader = bufferedReader; | ||
| } | ||
|
|
||
| public Request getRequest() throws IOException { | ||
| RequestLine requestLine = makeRequestLine(bufferedReader); | ||
|
|
||
| Map<String, String> headers = makeRequestHeaders(bufferedReader); | ||
| outputLog(headers); | ||
|
|
||
| String messageBody = ""; | ||
| if (requestLine.isPostMethodType()) { | ||
| messageBody = IOUtils.readData(bufferedReader, | ||
| Integer.parseInt(headers.get("Content-Length:"))); | ||
| log.debug(messageBody); | ||
| } | ||
|
|
||
| return new Request(requestLine, headers, messageBody); | ||
| } | ||
|
|
||
| private void outputLog(Map<String, String> headers) { | ||
| // Request Headers Log | ||
| for (Entry<String, String> entry : headers.entrySet()) { | ||
| log.debug("Request: {} {}", entry.getKey(), entry.getValue()); | ||
| } | ||
| } | ||
|
Comment on lines
+39
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굳이 필요없는 메서드로 보여요. 그냥 |
||
|
|
||
| private RequestLine makeRequestLine(BufferedReader bufferedReader) throws IOException { | ||
| String line; | ||
| if ("".equals(line = bufferedReader.readLine()) || line == null) { | ||
|
Comment on lines
+47
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런식의 할당과 비교를 동시에 수행하는 코드는 지양해주세요. (이런건 어디서 알려주나요??) |
||
| throw new IllegalArgumentException("Request.bufferedReader.readLine == null 입니다."); | ||
| } | ||
| // Request Line Log | ||
| log.debug(line); | ||
|
|
||
| String url = RequestLineUtil.getURL(line); | ||
| String methodType = RequestLineUtil.getMethodType(line); | ||
| return new RequestLine(methodType, url); | ||
| } | ||
|
|
||
| private Map<String, String> makeRequestHeaders(BufferedReader bufferedReader) | ||
| throws IOException { | ||
| Map<String, String> headers = new HashMap<>(); | ||
| String line; | ||
| while (!"".equals(line = bufferedReader.readLine())) { | ||
| if (line == null) { | ||
| throw new IllegalArgumentException("Request.bufferedReader.readLine == null 입니다."); | ||
| } | ||
| String[] splitLine = line.split(" "); | ||
| headers.put(splitLine[0], splitLine[1]); | ||
| } | ||
| return headers; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,23 +8,36 @@ public class Response { | |
|
|
||
| private byte[] body; | ||
| private String headers; | ||
| private String requestLine; | ||
| private String sessionId; | ||
| private RequestLine requestLine; | ||
| private URL url; | ||
|
|
||
| public Response(String requestLine, URL url) { | ||
| public Response(RequestLine requestLine, String sessionId) { | ||
| this.requestLine = requestLine; | ||
| this.url = url; | ||
| this.url = requestLine.getUrl(); | ||
| this.sessionId = sessionId; | ||
| } | ||
|
|
||
| public void action() throws IOException { | ||
| if (requestLine.contains("POST") && requestLine.contains("/user/create")) { | ||
| headers = response302Header(url); | ||
| } else { | ||
| body = Files.readAllBytes(new File("./webapp" + url.getPath()).toPath()); | ||
| headers = response200Header(body.length); | ||
| if (requestLine.isPostMethodType()) { | ||
| if (url.comparePath("/user/create")) { | ||
| headers = response302Header(url); | ||
| } | ||
| if (url.comparePath("/user/login")) { | ||
| headers = response302Header(url, sessionId, true); | ||
| } | ||
| } | ||
| if (requestLine.isGetMethodType()) { | ||
| if (url.comparePath("/user/logout")) { | ||
| headers = response302Header(url, sessionId, false); | ||
| } else { | ||
| body = Files.readAllBytes(new File("./webapp" + url.getPath()).toPath()); | ||
| headers = response200Header(body.length); | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
21
to
38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
|
|
||
| private String response200Header(int lengthOfBodyContent) { | ||
| StringBuilder sb = new StringBuilder(); | ||
| sb.append("HTTP/1.1 200 OK \r\n"); | ||
|
|
@@ -39,7 +52,23 @@ private String response302Header(URL url) { | |
| StringBuilder sb = new StringBuilder(); | ||
| sb.append("HTTP/1.1 302 Found \r\n"); | ||
| sb.append("Content-Type: text/html;charset=utf-8\r\n"); | ||
| sb.append("Location: " + url.getPath() + "\r\n"); | ||
| sb.append("Location: " + url.getRedirectPath() + "\r\n"); | ||
| sb.append("\r\n"); | ||
|
|
||
| return sb.toString(); | ||
| } | ||
|
|
||
| private String response302Header(URL url, String sessionId, boolean isLogin) { | ||
| StringBuilder sb = new StringBuilder(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| sb.append("HTTP/1.1 302 Found \r\n"); | ||
| sb.append("Content-Type: text/html;charset=utf-8\r\n"); | ||
| sb.append("Location: " + url.getRedirectPath() + "\r\n"); | ||
|
Comment on lines
+63
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 중복되는 코드가 등장하는데 중복제거를 해주세요. |
||
|
|
||
| if (isLogin) { | ||
| sb.append("Set-Cookie: sessionId = " + sessionId + "; Path=/\r\n"); | ||
| } else { | ||
| sb.append("Set-Cookie: sessionId = " + sessionId + "; max-age=0; Path=/\r\n"); | ||
| } | ||
|
Comment on lines
+67
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굳이 나눌 필요가 있을까요? |
||
| sb.append("\r\n"); | ||
|
|
||
| return sb.toString(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
왜
final을 사용하지 않고,HashMap을 사용해주신건가요?