끄적끄적 REST API !! OAUTH ?? <2>

Posted by lib oimb
2019. 3. 12. 01:19 TOPIC

지난 시간에 우린 REST API를 간단하지만 확실하게 알게 되었다. 오늘은 이 REST API를 이용해서 구현된? OAUTH를 공부 해볼 것이다. 

O A U T H ...? 벌써부터 어렵다. 나 또한 그랬다. 하지만 지금부터 함께 파헤쳐 보자



OAUTH는 위 그림과 같다.  그림을 보니 더 어렵다. 미리 공부하고 프로젝트를 경험한 나조차도 어렵다.. 

자 짤막짤막한 실선은 보지 말고 굵직한 노란선 3 가지를 보자. 저 세가지 선을 보면 알수 있듯이 3번의 과정을 거친다는 것을 알수 있다.


1. User가 로그인 시도 , 로그인 성공시 Auth Code와 함께 응답

2. Auth Code와 함께 다시 Server에 요청 , 요청 성공시 Access Token 으로 응답

3. 위 그림에는 생략되어져 있지만 Access Token을 이용해 사용자(로그인한 유저)의 정보를 Server에 요청 , 요청 성공시 사용자 정보를 리턴


위 와같은 3가지 과정을 거친다. 이것이 OAUTH 인증 방식이다. 끝이다. 더 어렵게 알고싶다면 (https://www.linkedin.com/pulse/oauth-token-processing-using-datapower-idg-part-1-20-julian-smiles/) 참고하길 바란다.


위 과정을 이해가 되어도 도대체 어떻게 정보를 주고받는다는 소린지는 이해가 잘 되지 않을 것이다. 그 과정을 살펴보자

우리가 API를 사용하게 된다면 보통 이런 형태로  설명 되어진다.(https://docs.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin/consumer/context)


보시다시피 예제 코드가 1도 없다. 하지만 우린 REST API가 무엇인지 알고 있다. 그리고 이해했다면 위 페이지를 읽는데에는 문제가 없을 것이다. 

우리는 LINKED IN 소셜 연동을 공부하는 것이 아닌 OAUTH를 이해하고 익히는것이 목적이므로 초기 세팅 과정은 생략하겠다. ( APP 만들고 설정해주는 등)


1



위 그림과 같이  설명되어져 있다. 이를 해석해보면 

GET 방식으로 아래 URL을 보내며 Parameter는 아래와 같다. 끝이다. 말그대로 " 해당 URL로 REST API 형태로 보내 " 라는 것이다. 즉


StringBuilder requestUrl = new StringBuilder( "https://www.linkedin.com/oauth/v2/authorization" + "?");

requestUrl.append("response_type=code");

requestUrl.append("&client_id=").append(linkedinClientId);

requestUrl.append("&redirect_uri=").append(param.getString("remoteDomain")+linkedinRedirectUrl);

requestUrl.append("&state=").append("987654321"); 

requestUrl.append("&scope=r_basicprofile,r_emailaddress,r_liteprofile");


형태로 String을 만든 후에 이 String을 Redirect시키거나 호출하면 된다.  끝


2


POST 방식으로 아래 URL을 보내고 Parameter는 아래와 같다. 는 동일하지만 여기서 중요한 것은 'code' 이다. 1번 과정에서 정상 호출이 되었다면 반드시

code가 request 형태로 응답이 온다.

그리고 한가지 더 REST API 공부 <1>에서 언급 했듯이 HTTP의 헤더와 바디부분이 예로 나와있다. 그렇다면 이를 어떻게 보낼것인가..? 헤더 부분은 동일하지만 바디 부분을 보낼수 있는 방법은 2가지가 있다.

알아 보자


1. HttpsURLConnection 을 이용하는 방법


      final String params = String.format("grant_type=authorization_code&client_id=%s&redirect_uri=%s&code=%s",

                        CLIENT_ID, REDIRECT_URI, code); // 이 부분은 더 길지만 생략 이런 느낌이란것만 알고 갑시다.


      final URL url = new URL(tokenRequestUrl);


      conn = (HttpsURLConnection) url.openConnection();

      conn.setRequestMethod("POST");


//add header

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

conn.setRequestProperty("Connection", "keep-alive");

...

      conn.setDoOutput(true);


      writer = new OutputStreamWriter(conn.getOutputStream());

      writer.write(params);

      writer.flush();


2. Apache HttpClient 라이브러리를 이용한 방법.


// [1] Http 생성

HttpClient client = HttpClientBuilder.create().build();


// [2] Http POST 생성

HttpPost post = new HttpPost(linkedinAuthHost + linkedinAccessTokenRequestUrl);


// [3] Header 설정

post.addHeader("Content-Type", "application/x-www-form-urlencoded");


// [4] 변수 세팅

List<NameValuePair> postParams = new ArrayList<NameValuePair>();

postParams.add(new BasicNameValuePair("grant_type", "authorization_code"));

postParams.add(new BasicNameValuePair("code", param.getString("code")));

postParams.add(new BasicNameValuePair("redirect_uri", param.getString("remoteDomain")+linkedinRedirectUrl));

postParams.add(new BasicNameValuePair("client_id", linkedinClientId));

postParams.add(new BasicNameValuePair("client_secret", linkedinClientSecret));


// [5] 변수 설정

post.setEntity(new UrlEncodedFormEntity(postParams, "UTF-8"));


// [6] REST API 요청

HttpResponse httpResponse = client.execute(post);



3


위 과정은 2번과 동일하며 다만 GET 방식이라는 점만 다르다 



오늘 우리는 REST API를 이용한 OAUTH 인증 방식을 공부 했으며 실제 코드로 요청을 어떻게 하는지를 알게 되었다 

마지막으로 공부할때 참고하시라고 URL 하나 남기고 가겠습니다.( https://devtalk.kakao.com/t/java-jsp-oauth-token-api-access-token/984 )

'TOPIC' 카테고리의 다른 글

끄적끄적 REST API !! OAUTH ?? <2>  (0) 2019.03.12
끄적끄적 REST API ? <1>  (0) 2019.03.12
IP address  (0) 2018.07.10
Call by Value or Reference in JAVA  (0) 2018.07.02
3-WAY Handshake  (0) 2018.06.27
Unicode,UTF  (0) 2018.06.25
이 댓글을 비밀 댓글로