Philo_sophia

[AWS] ZOOM JWT 지원 중단 조치 OAuth 연동 / Migrating to Server-to-Server OAuth from JWT 본문

[ Programing ]/[ Server ]

[AWS] ZOOM JWT 지원 중단 조치 OAuth 연동 / Migrating to Server-to-Server OAuth from JWT

Sophia_ 2023. 11. 29. 10:39

2023년 9월 8일부터 줌 API JWT가 지원 중단되었습니다.

따라서 기존에 JWT를 사용하던 프로그램에 OAuth 방식으로에 마이그레이션이 필요했습니다.

 

https://developers.zoom.us/docs/internal-apps/jwt/

 

JWT With Zoom

The Zoom Developer Platform is an open platform that allows third-party developers to build applications and integrations upon Zoom’s video-first unified communications platform.

developers.zoom.us

위 링크에서 살펴보면 JWT 앱 유형의 지원 중단에 따라 서버 간 OAuth 또는 OAuth 앱을 사용하여

JWT 앱의 기능을 대체하라는 문구와 함께 메뉴얼이 나와있습니다만...

친절하지 않은 메뉴얼을 보고 골치 좀 아프겠다 생각이 들었습니다.

결과적으로 토큰 요청 방식만 살짝 변경하면 되는 간단한 문제였지만

위 방식이 익숙치 않은 분들은 위해 간단히 포스팅을 작성합니다.

 

 

 

https://marketplace.zoom.us/

 

App Marketplace

 

marketplace.zoom.us

 

먼저 마켓플레이스에 접속하여 서버 간 OAuth 또는 OAuth 앱을 빌드해 줍니다.

 

 

 

 

Develop 목록에서 Build App을 클릭 후 OAuth 혹은 Server to Server OAuth를 Create 해줍니다.

저는 Server to Server OAuth 를 선택했습니다.

Create 하는 방법은 쉽게 찾아볼 수 있기에 생략하겠습니다.

 

 

 

생성 후 Manage에서 생성한 앱에 정보를 확인할 수 있습니다.

OAuth  사용을 위해선 App Credentials에서 할당받은 Account ID, Client ID, Client Secret 정보가 필요합니다.

 

 

 

 

OAuth  할당 후 포스트맨으로 테스트해보라는 메뉴얼데로 테스트를 진행했습니다.

Params에 grant_type을 account_credentials으로 정의하고

위에서 할당받은 account_id 또한 같이 넘겨줍니다.

 

Authorization 타입은 Basic으로 Username과 Password에는 마찬가지로 위에서 할당받은

Client ID와 Client Secret을 적어주고 Send를 해줍니다.

 

 

 

 

요청이 완료되면 보시는 바와 같이 access_token을 할당받을 수 있습니다.

다음으로는 소스에 적용을 하는 부분입니다.

다른 부분은 생략하고 토큰을 할당받는 부분만 살펴보겠습니다.

 

 

 

@Service("ZoomMeetingService")
public class ZoomMeetingServiceImpl extends EgovAbstractServiceImpl implements ZoomMeetingService {
    
    String zoomAccountId = EgovProperties.getProperty("zoom.accountId");
    String zoomClientId = EgovProperties.getProperty("zoom.clientId");
    String zoomClientSecret = EgovProperties.getProperty("zoom.clientSecret");

    private String generateZoomJWTTOken() {

    	String apiUrl = "https://zoom.us/oauth/token";
        
        /** encoding ClientId, ClientSecret */
    	String encodingText = zoomClientId + ":" + zoomClientSecret;
        byte[] targetBytes = encodingText.getBytes();
        Encoder encoder = Base64.getEncoder();
        
        byte[] encodedBytes = encoder.encode(targetBytes);
        encodingText = new String(encodedBytes);

    	/** Headers */
        RestTemplate restTemplate = new RestTemplate();
    	HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + encodingText);
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        
        /** parameters */
        MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
        parameters.add("grant_type", "account_credentials");
        parameters.add("account_id", zoomAccountId);

        /** http Request */
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(parameters, headers);
        
        ResponseEntity<String> zEntity = restTemplate.exchange(apiUrl, HttpMethod.POST, httpEntity, String.class);

        /** response */
        if(zEntity.getStatusCodeValue() == 200) {
            LOGGER.debug("Zooom meeeting response {}",zEntity);
            String resultData = zEntity.getBody();
            try {
            	JSONParser parser = new JSONParser();
                JSONObject jsonObject = (JSONObject) parser.parse(resultData);
                // JSON 객체의 값 읽어서 출력하기
                return jsonObject.get("access_token").toString();
			} catch (Exception e) {
				LOGGER.debug("Error get access_token {}", e);
				return "";
			}
        } else {
            LOGGER.debug("Error while creating zoom meeting {}", zEntity.getStatusCode());
        }

        return "";

    }

 

RestTemplate를 사용하여 통신하고 결과값으로 access_token을 리턴합니다.

이후 필요한 작업을 수행할 수 있습니다.

Comments