Yebali

Confluence Cloud Basic REST API 사용법 본문

Etc

Confluence Cloud Basic REST API 사용법

예발이 2021. 12. 14. 11:39

Confluence는 많은 기업들에서 사용하고 있는 협업 소프트웨어이다.

사용자들은 Blog나 Page를 만들어 지식이나 정보를 공유하기에 좋은 소프트웨어이다.

 

회사에서 JmsListener 자동 문서화 작업 중, 문서화된 내용을 Confluence 게시글에 업데이트하는 작업을 하며 알게 된 Confluence API 사용법을 조금 적어보겠다.

 

Confluence 자동 문서화 예제코드

 

참고로 confluence는 자신의 서버에 직접 설치하여 사용하거나 아틀라시안이 제공하는 서버에 월 요금을 내고 사용한다.

자신의 서버에 직접 운용하는 경우 'Server REST API'를 사용하고, 아틀라시안 서버를 사용하면 'Cloud REST API'를 사용한다.

이 글에서는  'Cloud REST API'를 사용하는 방법에 대해 기술할 것이다.

('Server REST API'가 필요한 분은 Server REST API 공식문서를 참고해주세요.)

 

Basic REST API

Basic Auth를 이용해 API를 사용하는 방법이다.

Basic Token 얻기

Basic Token을 얻기 위해서는 아래와 같은 절차를 거친다.

 

  1. Atlassian API Token 발급받기.
  2. Atlassian 계정과 Atlassian API Token의 조합으로 Basic Token 얻기.

1. Atlassian API Token 발급받기

Atlassian API Token에서 토큰을 만든다.

아래 사진들을 따라가면 쉽게 발급받을 수 있다.

API 토큰 만들기를 클릭하면 간단하게 토큰을 만들 수 있다.

 

Label은 자신이 기억하기 쉬운 아무 값이나 넣어도 된다.
위 토큰은 한번 밖에 볼 수 없기때문에 꼭 어딘가에 적어두는 것을 추천.

2. Atlassian 계정과 Atlassian API Token의 조합으로 Basic Token 얻기

이제 자신의 Atlassian 계정과 발급받은 API Token을 조합해서 Base64로 인코딩하면 된다.

계정과 API Token사이에는 콜론(:)을 넣어 구분해준다.

 

ex) yebali@htbeyond.com:RaRHORkRpwwXUljvWnUJ2280
-> Base64로 인코딩 
-> eWViYWxpQGh0YmV5b25kLmNvbTpSYVJIT1JrUnB3d1hVbGp2V25VSjIyODA=

 

이렇게 얻은 Token을 사용하면 된다.

Basic Rest API 사용하기

Kotlin에서 사용하기

아래의 의존성을 넣어준다. 버전은 자유롭게 해도 된다.

내가 굳이 쓰고 싶었던 건 아니고 Confluence Basic API 공식 문서에서 사용하고 있다.

implementation("com.mashape.unirest:unirest-java:1.3.1")

Unirest를 사용하여 아래와 같이 사용하면 해당 글의 개요를 볼 수 있다.

override fun request(): HttpResponse<JsonNode> {
    return Unirest.get("https://htbeyond.atlassian.net/wiki/rest/api/content/[Content No]")
      .header("Accept", "application/json")
      .header("Authorization", "Basic eWViYWxpQGh0YmV5b25kLmNvbTpSYVJIT1JrUnB3d1hVbGp2V25VSjIyODA=")
      .asJson()
}

만약 글의 내용을 보고 싶다면 아래처럼 query param에 'expand=body.view'을 추가해주어야 한다.

override fun request(): HttpResponse<JsonNode> {
    return Unirest.get("https://htbeyond.atlassian.net/wiki/rest/api/content/[Content No]?expand=body.view")
        .header("Accept", "application/json")
        .header("Authorization", "Basic eWViYWxpQGh0YmV5b25kLmNvbTpSYVJIT1JrUnB3d1hVbGp2V25VSjIyODA=")
        .asJson()
}

Confluence Basic Auth API 문서에는 GET 예시밖에 없지만 나머지 POST, PUT, DELETE도 가능하다.

body는 Confluence API REST API 문서를 참고하면 된다.

 

OAuth REST API

2021/11/24 기준으로 위의 OAuth 2.0 방식으로 얻은 Access Token으로는

The Confluence Cloud REST API에 나와있는 API를 사용할 수 없다 (401 Error 발생함)

OAuth 2.0 (3LO) apps3.2 Construct the request URL부분을 참고하여 URL을 적절히 수정하여 사용해야 한다.

Oauth Token 얻기

Oauth Token을 얻기 위해서는 아래와 같은 절차를 거친다.

 

  1. Confluence Oauth2(3LO) 인증용 App을 만든다.
  2. App에 필요한 권한들을 부여한다.
  3. Callback URL을 설정한다.
  4. Authorization Code 얻기
  5. Authorization Code로 Access Token 얻기
  6. (필요시) Refresh Access Token 얻기

Confluence Oauth2(3LO) 인증용 App 만들기

Confluence MyApp에서 인증용 앱을 만들면 된다. 이때 'OAuth 2.0 intergration'으로 만들면 된다.

App에 필요한 권한 부여하기

App 설정에서 'Permission > Confluence API'에 들어가 필요한 권한을 부여한다.

Callback URL 설정하기

'Authorization' 메뉴에 들어가면 Callback URL을 설정할 수 있다.

설정하고 나면 하단에 인증을 위한 URL이 자동으로 생성된다.

참고로 state값은 아무 값이나 넣어도 되지만, Refresh Token이 필요하다면 ‘scope’에 ‘offline_access’를 포함시켜야 한다.

Authorization Code 얻기

위의 과정에서 생성된 authorization URL를 브라우저에서 요청하면 아래와 같은 화면이 나온다.

Authorize for에 알맞은 confluence 선택하고 Accept 하면, 브라우저 URL에서 Authorization code를 얻을 수 있다.

http://localhost:8080/?code=cpYWEbZqZkX-iW-n&state=reservation

Authorization Code로 Access Token 얻기

Postman을 통해 아래처럼 요청하면 된다.

client_id, client_secret은 Myapps > Settings에서 얻을 수 있다.

  • URL : [POST] https://auth.atlassian.com/oauth/token
  • Request Body
    {
        "grant_type": "authorization_code",
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET",
        "code": "YOUR_AUTHORIZATION_CODE",
        "redirect_uri": "https://YOUR_APP_CALLBACK_URL"
    }
  • Request Body Example
    {
        "grant_type": "authorization_code",
        "client_id": "O1MvP2WwWeEqgrxn15JRdbFemWGtUoNn",
        "client_secret": "LgYejIrZKKAJEaYfDmPzGnJkC7A1KOK4D84Uh3sX_J_ZWywCHBf4K6cgZ9Fojpt-",
        "code": "BdjeQ3bffaBp0-mP", //Authorization code
        "redirect_uri": "http://localhost:8080"
    }
  • Response Body Example 
    {
        "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik16bERNemsxTVRoRlFVRTJRa0ZGT0VGRk9URkJOREJDTVRRek5EZzJSRVpDT1VKRFJrVXdNZyJ9.eyJodHRwczovL2F0bGFzc2lhbi5jb20vb2F1dGhDbGllbnRJZCI6Ik8xTXZQMld3V2VFcWdyeG4xNUpSZGJGZW1XR3RVb05uIiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL2VtYWlsRG9tYWluIjoiaHRiZXlvbmQuY29tIiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL3N5c3RlbUFjY291bnRJZCI6IjYxOTc1ZWY0ZWJjZTQ3MDA2N2Q1OGIzOSIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9zeXN0ZW1BY2NvdW50RW1haWxEb21haW4iOiJjb25uZWN0LmF0bGFzc2lhbi5jb20iLCJodHRwczovL2F0bGFzc2lhbi5jb20vdmVyaWZpZWQiOnRydWUsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9maXJzdFBhcnR5IjpmYWxzZSwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tLzNsbyI6dHJ1ZSwiaXNzIjoiaHR0cHM6Ly9hdGxhc3NpYW4tYWNjb3VudC1wcm9kLnB1czIuYXV0aDAuY29tLyIsInN1YiI6ImF1dGgwfDYxMzA0ZDlhNGE5OGRhMDA2OWQ3NzNiNCIsImF1ZCI6ImFwaS5hdGxhc3NpYW4uY29tIiwiaWF0IjoxNjM3NzI4MDIxLCJleHAiOjE2Mzc3MzE2MjEsImF6cCI6Ik8xTXZQMld3V2VFcWdyeG4xNUpSZGJGZW1XR3RVb05uIiwic2NvcGUiOiJtYW5hZ2U6Y29uZmx1ZW5jZS1jb25maWd1cmF0aW9uIHNlYXJjaDpjb25mbHVlbmNlIHdyaXRlOmNvbmZsdWVuY2UtcHJvcHMgcmVhZDpjb25mbHVlbmNlLXByb3BzIHdyaXRlOmNvbmZsdWVuY2UtZmlsZSB3cml0ZTpjb25mbHVlbmNlLXNwYWNlIHJlYWQ6Y29uZmx1ZW5jZS1zcGFjZS5zdW1tYXJ5IHdyaXRlOmNvbmZsdWVuY2UtY29udGVudCByZWFkOmNvbmZsdWVuY2UtY29udGVudC5zdW1tYXJ5IHJlYWQ6Y29uZmx1ZW5jZS1jb250ZW50LmFsbCByZWFkOmNvbmZsdWVuY2UtZ3JvdXBzIHdyaXRlOmNvbmZsdWVuY2UtZ3JvdXBzIHJlYWQ6Y29uZmx1ZW5jZS11c2VyIHJlYWQ6Y29uZmx1ZW5jZS1jb250ZW50LnBlcm1pc3Npb24gcmVhZG9ubHk6Y29udGVudC5hdHRhY2htZW50OmNvbmZsdWVuY2Ugb2ZmbGluZV9hY2Nlc3MifQ.fHBw-UkEqPNNDTfNzu5aqjjjaFVGzE6ndELeQVkW0orBHTjAi9zhHlQM2jVYbqp-ZrXiG7tGOv2b8iV7-jIJZox7AzSQLZK4HRNrFQ8W8qxh3WnHGcRZtGnYalwhW4MFT3qgOJ_Jr-RPR9WH6XpOwEeVj-uvy7s7C446uSCl_NdAHEUlx8VnF6OZBVx6C_AlcJT1lwPiteUEq0YYf-xw7oH-rCVcsuzVhWrmacR-T5YjVftI-U6IyAgtAIxXk2-869WbnPpNR_b-0M3ESrQo3AAnSVcmRS-Xomu0jybUcMuq6MIHv2r4shwKTVxtcq6iBwDZRiPrrex25MEvLE1Q-A",
        "refresh_token": "v1.MQFdtSM-SJhbBDfX-sdnBeIyAnkwKgl5fYby7-wzp46OPtIr880goHcXWaRS9qLjcrQ6dgu5KPDU_uaTBTxJkyc",
        "scope": "manage:confluence-configuration search:confluence write:confluence-props read:confluence-props write:confluence-file write:confluence-space read:confluence-space.summary write:confluence-content read:confluence-content.summary read:confluence-content.all read:confluence-groups write:confluence-groups read:confluence-user read:confluence-content.permission readonly:content.attachment:confluence offline_access",
        "expires_in": 3600,
        "token_type": "Bearer"
    }​
     

위의 'access_token'이 Oauth 인증의 결과물이다.

Refresh Access Token

Access Token은 약 1시간 정도의 수명을 지닌다. Access Token이 만료된 경우 새로운 Access Token을 받아야 한다.

  • URL : [POST] https://auth.atlassian.com/oauth/token 
  • Request Body
    {
        "grant_type": "refresh_token",
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET",
        "refresh_token": "YOUR_REFRESH_TOKEN"
    }​
  • Request Body Example
    {
        "grant_type": "refresh_token",
        "client_id": "O1MvP2WwWeEqgrxn15JRdbFemWGtUoNn",
        "client_secret": "LgYejIrZKKAJEaYfDmPzGnJkC7A1KOK4D84Uh3sX_J_ZWywCHBf4K6cgZ9Fojpt-",
        "refresh_token": "v1.MgFdtSM-SJhbBDfX-sdnBeIMQKB9qx-cUGELoWqLt7lGOvy8zji5KDPz5PkGjRxDUXoIqPxx3sOZDiYiWCETrHo"
    }​
  • Response Body Example
    {
        "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik16bERNemsxTVRoRlFVRTJRa0ZGT0VGRk9URkJOREJDTVRRek5EZzJSRVpDT1VKRFJrVXdNZyJ9.eyJodHRwczovL2F0bGFzc2lhbi5jb20vb2F1dGhDbGllbnRJZCI6Ik8xTXZQMld3V2VFcWdyeG4xNUpSZGJGZW1XR3RVb05uIiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL2VtYWlsRG9tYWluIjoiaHRiZXlvbmQuY29tIiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL3N5c3RlbUFjY291bnRJZCI6IjYxOTc1ZWY0ZWJjZTQ3MDA2N2Q1OGIzOSIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9zeXN0ZW1BY2NvdW50RW1haWxEb21haW4iOiJjb25uZWN0LmF0bGFzc2lhbi5jb20iLCJodHRwczovL2F0bGFzc2lhbi5jb20vdmVyaWZpZWQiOnRydWUsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9maXJzdFBhcnR5IjpmYWxzZSwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tLzNsbyI6dHJ1ZSwiaXNzIjoiaHR0cHM6Ly9hdGxhc3NpYW4tYWNjb3VudC1wcm9kLnB1czIuYXV0aDAuY29tLyIsInN1YiI6ImF1dGgwfDYxMzA0ZDlhNGE5OGRhMDA2OWQ3NzNiNCIsImF1ZCI6ImFwaS5hdGxhc3NpYW4uY29tIiwiaWF0IjoxNjM3NzM1NTQ5LCJleHAiOjE2Mzc3MzkxNDksImF6cCI6Ik8xTXZQMld3V2VFcWdyeG4xNUpSZGJGZW1XR3RVb05uIiwic2NvcGUiOiJtYW5hZ2U6Y29uZmx1ZW5jZS1jb25maWd1cmF0aW9uIHNlYXJjaDpjb25mbHVlbmNlIHdyaXRlOmNvbmZsdWVuY2UtcHJvcHMgcmVhZDpjb25mbHVlbmNlLXByb3BzIHdyaXRlOmNvbmZsdWVuY2UtZmlsZSB3cml0ZTpjb25mbHVlbmNlLXNwYWNlIHJlYWQ6Y29uZmx1ZW5jZS1zcGFjZS5zdW1tYXJ5IHdyaXRlOmNvbmZsdWVuY2UtY29udGVudCByZWFkOmNvbmZsdWVuY2UtY29udGVudC5zdW1tYXJ5IHJlYWQ6Y29uZmx1ZW5jZS1jb250ZW50LmFsbCByZWFkOmNvbmZsdWVuY2UtZ3JvdXBzIHdyaXRlOmNvbmZsdWVuY2UtZ3JvdXBzIHJlYWQ6Y29uZmx1ZW5jZS11c2VyIHJlYWQ6Y29uZmx1ZW5jZS1jb250ZW50LnBlcm1pc3Npb24gcmVhZG9ubHk6Y29udGVudC5hdHRhY2htZW50OmNvbmZsdWVuY2Ugb2ZmbGluZV9hY2Nlc3MifQ.zfMsw-Z0BqH9zBVxkHWET_EV0xpriMwzf4gbE7RHVLwtdEMg-FxpdpTXy2Fot2xu1hh-KtmZkQ9McCOJfZORtggTD7pYRwdFutSaA1nzdgNHJg7IXucp5YeNh3m0x0amsvYTK6f7YUslJ4_Nm4-Te6G2J1_LrP-KTC0w2bEsloSptNc-4rTbv1WulvBXwtu_Jn7fmJrJwdWZvAVvp2YdycD1TRw2lzy7dKr32XZpphjn2RMN5-4-MHbaGOFnGvXT8lowWa4WVFBHRmSQxezQDkv0vwSlSACw-rLq-Z1TkNYOfvXr0Y8KjeLTuxRTxM59tNrtwFv8kJhEyBG4hsbqyg",
        "refresh_token": "v1.MwFdtSM-SJhbBDfX-sdnBeKIB-U1eyCUMFQv1vsQpFT44Vz1t79kSmg910SEaa-I3Lc9_4RCRJYD6f15XFP7ojU",
        "scope": "manage:confluence-configuration search:confluence write:confluence-props read:confluence-props write:confluence-file write:confluence-space read:confluence-space.summary write:confluence-content read:confluence-content.summary read:confluence-content.all read:confluence-groups write:confluence-groups read:confluence-user read:confluence-content.permission readonly:content.attachment:confluence offline_access",
        "expires_in": 3600,
        "token_type": "Bearer"
    }​

Cloud Id 얻기

Cloud REST API를 사용하기 위해서는 Confluence의 Cloud Id를 알아야 한다.

위에서 얻은 access_token과 함께 아래 요청을 하면 알 수 있다.

  • URL : [GET] https://api.atlassian.com/oauth/token/accessible-resources
  • Response Body Example
    [
        {
            "id": "dd41eeba-d615-4e8c-9f41-2c4c467b2249",
            "url": "https://htbeyond.atlassian.net",
            "name": "htbeyond",
            "scopes": [
                "read:confluence-space.summary",
                "write:confluence-content",
                "read:confluence-content.summary",
                "read:confluence-content.all",       
            ],
            "avatarUrl": "https://site-admin-avatar-cdn.prod.public.atl-paas.net/avatars/240/star.png"
        }
    ]​

응답 중 id의 값이 Cloud Id이다.

 

예제

 

 

'Etc' 카테고리의 다른 글

[Jenkins] Jenkins를 이용한 CI/CD  (0) 2022.09.11
GitHub Action으로 PR 마다 빌드 테스트 하기  (0) 2022.01.25
Confluence OAuth 2.0 인증하기  (0) 2021.12.14
Git 사용법  (0) 2021.10.30