diff --git a/src/main/java/org/yj/sejongauth/controller/Sj.java b/src/main/java/org/yj/sejongauth/controller/Sj.java index 0ecc392..c25ec12 100644 --- a/src/main/java/org/yj/sejongauth/controller/Sj.java +++ b/src/main/java/org/yj/sejongauth/controller/Sj.java @@ -18,7 +18,7 @@ public Sj(AuthService authService, ProfileService profileService){ public SjProfile login(String userId, String password) { if (authService.authenticate(userId, password)) { - String jsessionId = authService.getJsessionId(); + String jsessionId = authService.getSsoToken(); return profileService.fetchUserProfile(jsessionId); } else { throw new RuntimeException("인증에 실패하였습니다."); diff --git a/src/main/java/org/yj/sejongauth/domain/AuthService.java b/src/main/java/org/yj/sejongauth/domain/AuthService.java index cb3fe7b..7386914 100644 --- a/src/main/java/org/yj/sejongauth/domain/AuthService.java +++ b/src/main/java/org/yj/sejongauth/domain/AuthService.java @@ -2,101 +2,69 @@ -import java.io.BufferedReader; import java.io.IOException; import java.io.OutputStream; -import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; import java.net.URLEncoder; -import org.springframework.stereotype.Service; public class AuthService { - private String jsessionId; - private final String SJ_LOGIN_URL = "https://classic.sejong.ac.kr/userLogin.do"; - private final String SJ_POTAL_URL = "https://classic.sejong.ac.kr"; + private String ssoToken; + private final String PORTAL_LOGIN_URL = "https://portal.sejong.ac.kr/jsp/login/login_action.jsp"; private final String INVALID_AUTH = "인증이 실패하였습니다."; - private final String INVALID_SESSION = "SESSION_ID 가져오는 것을 실패하였습니다."; + private final String INVALID_SESSION = "SSO Token 가져오는 것을 실패하였습니다."; private final String INVALID_URL = "URL이 유효하지 않습니다."; - private final String CONTAINS_HTML = "로그인 정보가 올바르지 않습니다."; public boolean authenticate(String userId, String password) { LoginReq loginReq = new LoginReq(userId, password); try { - fetchJsessionId(); + System.out.println(attemptLogin(loginReq)); return attemptLogin(loginReq); } catch (IOException e) { throw new RuntimeException(INVALID_AUTH); } } - void fetchJsessionId() throws IOException { - try { - URI uri = new URI(SJ_POTAL_URL); - HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection(); - connection.setRequestMethod("GET"); - connection.connect(); - - Map> headers = connection.getHeaderFields(); - List cookies = headers.get("Set-Cookie"); - - if (cookies != null) { - for (String cookie : cookies) { - if (cookie.startsWith("JSESSIONID")) { - jsessionId = cookie.split(";")[0].split("=")[1]; - break; - } - } - } - - if (jsessionId == null) { - throw new RuntimeException(INVALID_SESSION); - } - } catch (URISyntaxException e) { - throw new RuntimeException(INVALID_URL); - } - } - private boolean attemptLogin(LoginReq loginReq) throws IOException { try { - URI uri = new URI(SJ_LOGIN_URL); + URI uri = new URI(PORTAL_LOGIN_URL); HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection(); connection.setRequestMethod("POST"); - connection.setRequestProperty("Cookie", "JSESSIONID=" + jsessionId); + connection.setRequestProperty("Referer", "https://portal.sejong.ac.kr/jsp/login/loginSSL.jsp"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setDoOutput(true); - String postData = "userId=" + URLEncoder.encode(loginReq.getUserId(), StandardCharsets.UTF_8.toString()) + - "&password=" + URLEncoder.encode(loginReq.getPassword(), StandardCharsets.UTF_8.toString()); + String postData = "mainLogin=Y" + + "&rtUrl=" + URLEncoder.encode("https://classic.sejong.ac.kr/classic/index.do", StandardCharsets.UTF_8.toString()) + + "&id=" + URLEncoder.encode(loginReq.getUserId(), StandardCharsets.UTF_8.toString()) + + "&password=" + URLEncoder.encode(loginReq.getPassword(), StandardCharsets.UTF_8.toString()) + + "&chkNos=on"; + try (OutputStream os = connection.getOutputStream()) { byte[] input = postData.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } int responseCode = connection.getResponseCode(); - String responseMessage = readResponse(connection); - return responseCode == 302 && !responseMessage.contains(CONTAINS_HTML); - } catch (URISyntaxException e) { - throw new RuntimeException(INVALID_URL); - } - } + if (responseCode != 200) { + return false; + } - private String readResponse(HttpURLConnection connection) throws IOException { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - StringBuilder response = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - response.append(line); + String cookie = connection.getHeaderField("Set-Cookie"); + if (cookie != null && cookie.contains("ssotoken=")) { + ssoToken = cookie.substring(cookie.indexOf("ssotoken=") + 9, cookie.indexOf(";", cookie.indexOf("ssotoken="))); + return true; } - return response.toString(); + return false; + + } catch (URISyntaxException e) { + throw new RuntimeException(INVALID_URL); } } - public String getJsessionId() { - return jsessionId; + public String getSsoToken() { + return ssoToken; } } diff --git a/src/main/java/org/yj/sejongauth/domain/ProfileService.java b/src/main/java/org/yj/sejongauth/domain/ProfileService.java index b470cba..623ee92 100644 --- a/src/main/java/org/yj/sejongauth/domain/ProfileService.java +++ b/src/main/java/org/yj/sejongauth/domain/ProfileService.java @@ -7,23 +7,21 @@ import java.net.URL; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; -import org.springframework.stereotype.Service; public class ProfileService { - private final String PROFILE_URL = "http://classic.sejong.ac.kr/userCertStatus.do?menuInfoId=MAIN_02_05"; - private final String FAIDED_PROFILE = "정보 조회에 실패하였습니다."; + private final String CLASSIC_URL = "https://classic.sejong.ac.kr/classic/reading/status.do"; + private final String FAILED_PROFILE = "정보 조회에 실패하였습니다."; - public SjProfile fetchUserProfile(String jsessionId) { + public SjProfile fetchUserProfile(String ssoToken) { try { - URL url = new URL(PROFILE_URL); + URL url = new URL(CLASSIC_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); - connection.setRequestProperty("Cookie", "JSESSIONID=" + jsessionId); - + connection.setRequestProperty("Cookie", "ssotoken=" + ssoToken); Document doc = Jsoup.parse(readResponse(connection)); return parseProfileFromHtml(doc); } catch (IOException e) { - throw new RuntimeException(FAIDED_PROFILE); + throw new RuntimeException(FAILED_PROFILE); } } @@ -39,14 +37,10 @@ private String readResponse(HttpURLConnection connection) throws IOException { } private SjProfile parseProfileFromHtml(Document document) { - String major = document.select("div.contentWrap li dl dd").get(0).text(); - String studentCode = document.select("div.contentWrap li dl dd").get(1).text(); - String name = document.select("div.contentWrap li dl dd").get(2).text(); - int gradeLevel = Integer.parseInt(document.select("div.contentWrap li dl dd").get(3).text().split(" ")[0]); - String userStatus = document.select("div.contentWrap li dl dd").get(4).text(); - int completedSemesters = Integer.parseInt(document.select("div.contentWrap li dl dd").get(5).text().split(" ")[0]); - int verifiedSemesters = Integer.parseInt(document.select("div.contentWrap li dl dd").get(6).text().split(" ")[0]); + String major = document.select("th:contains(학과명) + td").text().trim(); + String name = document.select("th:contains(이름) + td").text().trim(); + String userStatus = document.select("th:contains(사용자 상태) + td").text().trim(); - return new SjProfile(major, studentCode, name, gradeLevel, userStatus, completedSemesters, verifiedSemesters); + return new SjProfile(major, name, userStatus); } -} \ No newline at end of file +} diff --git a/src/main/java/org/yj/sejongauth/domain/SjProfile.java b/src/main/java/org/yj/sejongauth/domain/SjProfile.java index fe6d63e..e09669a 100644 --- a/src/main/java/org/yj/sejongauth/domain/SjProfile.java +++ b/src/main/java/org/yj/sejongauth/domain/SjProfile.java @@ -2,30 +2,16 @@ public class SjProfile { private final String major; - private final String studentCode; private final String name; - private final int gradeLevel; private final String userStatus; - private final int completedSemesters; - private final int verifiedSemesters; - public SjProfile(String major, String studentCode, String name, - int gradeLevel, String userStatus, - int completedSemesters, int verifiedSemesters) { + public SjProfile(String major, String name, String userStatus) { this.major = major; - this.studentCode = studentCode; this.name = name; - this.gradeLevel = gradeLevel; this.userStatus = userStatus; - this.completedSemesters = completedSemesters; - this.verifiedSemesters = verifiedSemesters; } public String getMajor() { return major; } - public String getStudentCode() { return studentCode; } public String getName() { return name; } - public int getGradeLevel() { return gradeLevel; } public String getUserStatus() { return userStatus; } - public int getCompletedSemesters() { return completedSemesters; } - public int getVerifiedSemesters() { return verifiedSemesters; } } \ No newline at end of file diff --git a/src/test/java/org/yj/sejongauth/domain/AuthServiceTest.java b/src/test/java/org/yj/sejongauth/domain/AuthServiceTest.java index 601ae30..8b26482 100644 --- a/src/test/java/org/yj/sejongauth/domain/AuthServiceTest.java +++ b/src/test/java/org/yj/sejongauth/domain/AuthServiceTest.java @@ -21,7 +21,6 @@ void setUp() { @Disabled void testAuthenticate_Success() throws IOException { // Given - authService.fetchJsessionId(); //when boolean isAuthenticated = authService.authenticate("학번", "비번");