티스토리 뷰

반응형

 왜 OAuth2 인증 관련하여 CORS를 찾게되었냐면,
API Server와 Web application이 따로 올라가고,
웹 사이트에서는 API만 호출해서 사용하는 용도로 사용할려고 하다보니
CORS문제가 생겼다.

(CORS Filter 적용 내용은 아래 링크 참조.)
http://kkforgg.blog.me/220762949663

https://spring.io/guides/tutorials/spring-security-and-angular-js/

위 가이드를 보면 Spring + AngularJS 관련 내용을 볼 수 있는데.
이 예제에서 OAuth2를 사용하는 것이 나온다.

아무튼 이런 방법으로 작업을 하려다보니 다른 도메인으로 호출하는 문제가 생겼고
그에 따라서 방법을 찾다가 아래와 같이 샘플 코드를 작성해보았다.

단순히 인증 토큰 발급 후 발급받은 Access_token으로 Test API호출 하는 정도 이다.

서버 관련된 정보는 내 개인프로젝트 내용하고도 좀 겹치는 부분이 있기 때문에 나중에 추려서 작성할 예정.

기본적으로 OAuth 설정에서 CSRF Filter는 자체적으로 disabled 시킨 상태이다.

Resource 서버 설정 부분

@Configuration @EnableResourceServer // API 서버 인증(또는 권한 설정 protected static class ResourceServer extends ResourceServerConfigurerAdapter { @Autowired private TokenStore tokenStore; @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenStore(tokenStore); } @Override public void configure(HttpSecurity http) throws Exception { http.csrf() .disable(); http.authorizeRequests().anyRequest().authenticated(); } }



jquery 버전
IE9까지 확인.

<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Hello Jquery OAuth2 Test</title> </head> <body > <div class="container"> <div id="result"> </div> <input type="button" value="토큰 발급" id="btn" /> </div> <div > <div id="result2"></div> <input type="button" value="값 가져오기" id="btn2" /> </div> </body> <script src="https://code.jquery.com/jquery-2.2.4.min.js" type="text/javascript"></script> <script type="text/javascript"> // IE9 CORS No Transfer 관련 jquery 추가사항. $.support.cors = true; // 인증 access token var access_token; var client_id = '클라이언트ID'; var client_secret = '시크릿'; $("#btn").click(function() { console.log('btn'); var token; if(window.btoa) { token = btoa(client_id + ":" + client_secret); } else { // IE9 관련 예외 사항 token = b64(client_id + ":" + client_secret); } $.ajax({ type : 'POST', url : 'http://URL/v1/oauth/token?grant_type=client_credentials', data : 'grant_type=client_credentials', dataType:'json', headers : { "Authorization" : "Basic " + token, "Content-Type" : "form-data" } }).success(function(result) { console.log(result); $("#result").text(JSON.stringify(result)); access_token = result.access_token; }); }) $("#btn2").click(function() { if(!access_token) { $("#result2").text('토큰을 발급 받으세요.'); return; } else { $("#result2").text(''); } $.ajax({ headers : { "authorization" : "bearer " + access_token }, type : "GET", url : 'http://URL/v1/test', dataType : 'text' }) .then(function(data) { $("#result2").text(data); }, function(data) { $("#result2").text(JSON.stringify(data)); }) }) // 출처 : http://ohgyun.com/432 function b64(s) { var key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; var i = 0, len = s.length, c1, c2, c3, e1, e2, e3, e4, result = []; while (i < len) { c1 = s.charCodeAt(i++); c2 = s.charCodeAt(i++); c3 = s.charCodeAt(i++); e1 = c1 >> 2; e2 = ((c1 & 3) << 4) | (c2 >> 4); e3 = ((c2 & 15) << 2) | (c3 >> 6); e4 = c3 & 63; if (isNaN(c2)) { e3 = e4 = 64; } else if (isNaN(c3)) { e4 = 64; } result.push(e1, e2, e3, e4); } return result.map(function (e) { return key.charAt(e); }).join(''); } </script> </html>

AngularJS 예제
모던웹이기 때문에 과감히 IE는 무시 ^^;

<!doctype html> <html ng-app="testApp"> <head> <meta charset="UTF-8"> <title>Hello AngularJS OAuth2 Test Page</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> </head> <body ng-controller="testController"> <div class="container"> <div id="result" > {{result}} </div> <input type="button" value="토큰 발급" id="btn" ng-click="btn1()" /> </div> <div > <div id="result2"> {{result2}} </div> <input type="button" value="값 가져오기" id="btn2" ng-click="btn2()"/> </div> </body> <script type="text/javascript"> var app = angular.module('testApp',[]) app.controller('testController',function($scope, $http) { var client_id = '클라이언트ID'; var client_secret = '시크릿'; // 인증 access token var access_token; $scope.btn1 = function() { console.log('btn1'); $http({ method : 'POST', headers : { 'authorization' : 'Basic ' + btoa(client_id + ":" + client_secret) }, url : 'http://URL/v1/oauth/token?grant_type=client_credentials' }) .then(function(result) { console.log(result.data.access_token); $scope.result = JSON.stringify(result.data); access_token = result.data.access_token; }) } $scope.btn2 = function() { console.log('btn2'); if(!access_token) { $scope.result2 = '토큰을 발급 받으세요.'; return; } $scope.result2 = ''; console.log(access_token); $http({ method : 'GET', headers : { "authorization" : "bearer " + access_token }, url : 'http://URL/v1/test', transformResponse : function(data, header){ var result = JSON.stringify(data); return result; } }) .success(function(result) { console.log(result); $scope.result2 = result; }) } }) </script> </html>

OAuth Token 발급 후 /test Controller

@RestController public class OAuthTestController { @RequestMapping(value = "/test") public String oauthTest() { return "hello world"; } }

결과

 


반응형