Spring Kotlin 소셜로그인 구현 및 no space left on device 문제 해결

최은지·2022년 4월 1일
0
post-thumbnail

학교 과제 제출 용으로, 토이프로젝트를 수행하였는데.. 소셜로그인과 배포과정에서 오랜 시간이 소요되었다. 재발 방지를 위해 기록한다.

소셜 로그인 구현

그 당시 검색을 해도 Kotlin으로 소셜로그인 구현한 내용을 찾기가 어려웠다. Security를 사용하지 않고 기본 소셜로그인만 작성하고 싶었는데, 의외로 나오지 않았었다.

그래서 Spring에서 HTTP 요청 시 사용하는 RestTemplate 을 찾아서 기본 소셜로그인 로직대로 코드를 작성해보았다. 참고

소셜로그인 절차는 다음과 같다. 참고

  1. developer 페이지에 방문하여 나만의 clientSecret을 발급받는다.
  2. Redirect URI를 설정한다.
  3. 사용자가 로그인 이후 정보를 얻어 올 수 있도록 URI에 접근한다.
  4. 로그인 이후 사용자의 access_token 값을 얻어온다.
  5. access_token 값으로 사용자의 정보를 얻어 온 후, 자신의 서비스에 맞게 소셜 로그인을 구현한다.

기억할 사항은 다음과 같다.

RestTemplate을 이용해 Kakao에 위와 같이 요청 한다.
그리고 json을 body에 넣기 위해 LinkedMultiValueMap을 사용하며, HttpHeaders를 활용하여 header 값을 삽입한다.

코드 작성 전 clientSecret을 발급받는다.

fun getOauthRedirectURL(): String {
        return (kakaoLoginUrl.toString() + 
        "/oauth/authorize?response_type=code&client_id=" 
        + kakaoClientId + "&redirect_uri=" + kakaoRedirectUrl)
    }

자신의 정보를 기입 후 return되는 링크로 접속하면 로그인 창이 나타난다.
로그인을 하면 code를 받을 수 있다.

code를 활용하여 access_token을 얻기 위한 추가 요청을 수행한다.

fun requestAccessToken(code: String): String {
        val restTemplate = RestTemplate(); // 요청을 위한 RestTemplate
        val data = LinkedMultiValueMap<String, String>()
        data["grant_type"] = "authorization_code"
        data["client_id"] = kakaoClientId
        data["redirect_uri"] = kakaoRedirectUrl
        data["client_secret"] = kakaoClientSecret
        data["code"] = code
		// Http Reqeust의 body에 담기는 값들. POST 요청을 수행할 것이다.

        val headers = HttpHeaders()
        headers.contentType = MediaType.APPLICATION_FORM_URLENCODED
		// Header 설정 값
        
        val request = HttpEntity<MultiValueMap<String, String>>(data, headers)
        

        try {
            val response = restTemplate
            		.postForEntity(kakaoTokenBaseUrl, request, Map::class.java) 
            val responseBody = response.getBody()
            val token = responseBody?.get("access_token").toString()
            // 요청 후 응답 값으로 Token 발급
            return token
        } catch (e: HttpClientErrorException) {
            println(e)
        }
        return ""; 
    }

토큰을 얻어온 후, 이를 활용해 사용자 정보를 얻기 위한 요청을 할 수 있다.

 fun getKakaoUserInfo(token: String): Map<*, *>? {
        val requestUrl = "https://kapi.kakao.com/v2/user/me";
        val restTemplate = RestTemplate()
        val headers = HttpHeaders()
        headers.set("Authorization", "Bearer $token")
        headers.set("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")

        val request = HttpEntity<MultiValueMap<String, String>>(headers)
        val response = restTemplate
                       .exchange(requestUrl, HttpMethod.GET, request, Map::class.java)
        val body = response.getBody()
        return body
    }

사용자 정보 얻어오기 성공!
이후에는 사용자 정보를 활용해 본인의 프로젝트에서 수행하는 로직에 따라 추가 코드를 작성하면 된다.

No Space Left On Device 문제 해결

이후, 프로젝트를 완료하고 배포를 Amazon EC2에 시도했다.
배포하기 위해 만들어 둔 인스턴스에 Spring 프로젝트를 올리고 build 및 배포를 시도했는데, 지속적인 build 실패 오류가 발생하였다.

Error 내용은

no space left on device.
말 그대로 저장 공간이 없단다.

df-h 를 입력해 살펴보니, 현재 8gb가 할당되어 있었고 이를 100% 사용 중 이었다.

  1. 우선 용량이 없으면 어떻게 할까? 용량을 늘려주어야 한다. 이를 위해 AWS 콘솔에 접속하였다. EBS 볼륨이 8gb 였기에 16gb까지 확장시켰다.
  1. 인스턴스의 볼륨 파티션 확장하기
    AWS 콘솔을 통한 볼륨 확장 이후 파티션을 확장해주어야 한다.

lsblk
sudo growpart /dev/xvda 1 //파티션 확장
df –h
sudo resize2fs /dev/xvda1 //디스크 공간 확장

하지만, build는 여전히 되지 않았고, 인스턴스가 중단되어 여러번 껐다 키는 현상이 발생했다. -> MYSQL 서버도 멈춰버렸다.
공간이 늘어나 사용하고 있는 용량은 50%로 바뀌었지만, 내가 늘린 공간은 Disk 공간이기에 당연히 작동하지 않는다.

  1. Swap Memory 할당
    갑자기? Swap? 일까 싶지만 여기서 우리는 OS의 메모리 관리 전략을 알면 이유를 유추해볼 수 있다.
    운영체제는 메모리를 관리하기 위해, 가상 메모리를 사용한다. 실제 물리 메모리는 한정되어 있기에, 보다 효율적으로 관리하기 위함이다.

가상메모리는 페이지 단위로 나뉘며, 관련 정보를 페이지 테이블에 저장한다.
자세히 알기 위해서는 페이징 기법, 세그먼테이션 기법을 찾아보자.

Swap은 메모리가 부족할 경우 하드 디스크의 일부 공간을 활용하여 작업을 진행할 수 있도록 돕는 영역이다.
프로세스가 사용하는 메모리 중 Inactive 상태에 있는 메모리를 골라서 Swap 영역으로 이동 시킨다. 그 다음 해당 메모리 영역을 해제하고 다른 프로세스에 할당하게 된다.

나의 문제는 RAM 의 크기가 작았고, Swap 영역 또한 작았기에 그 이상의 메모리 사용량을 요구하는 프로세스를 가동 시킬 수 없었던 문제였다.

간단한 해결책은 RAM 크기를 증가시키는 것인데, Amazon EC2 프리티어를 사용하고 있었고, RAM 크기를 증가 시킬 수 없었다.

때문에 임시 방편으로 하드디스크를 RAM처럼 사용할 수 있도록 Swap을 확장함으로써 해결할 수 있는 것이다.
하지만, Swap을 사용하게 되면 성능의 저하가 있다. 하드디스크에 위치하기에 접근 속도가 느리다.

Swap을 늘리기 위한 방법은?

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-memory-swap-file/

위의 링크를 따라하면 Swap 공간을 증가시킬 수 있다.
이렇게 하면 build가 잘 수행되고, 서버도 잘 돌아가는 것을 확인할 수 있다.

Reference

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-memory-swap-file/
https://sundries-in-myidea.tistory.com/102
https://flowingmooon.tistory.com/m/22

profile
배고파

0개의 댓글