22
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RedmineAdvent Calendar 2017

Day 7

RedmineのJavaScriptからREST APIを使用する

Last updated at Posted at 2017-12-03

JavaScriptからでもRedmineのREST APIを実行することはできる。
しかしREST APIの実行にはBASIC認証かログインユーザーのapikeyが必要になる。

この記事では少々トリッキーながらJavaScriptからログインユーザーのapikeyを取得し、実際にREST APIを実行してみる。

動作確認は Redmine 2.6系 で行った。

REST APIを使わず、チケット一覧のコンテキストメニューが使用するbulk_updateを利用する記事はこちら。
RedmineのJavaScriptからbulk_updateを使用する

ログインユーザーのapikeyの取得

apikeyを取得するようなAPIは存在しない。
よってログインユーザーの「個人設定」をスクレイピングして取得する。
(下記コードは、当然ながらRedmineのバージョンアップなどで動かなくなる可能性はある)

// Redmine 3.1以前版。
// 3.1以降のいずれかのバージョンからはajaxでapikeyが埋め込まれるためこの方法だと失敗する。
// REST APIがONになっていなければapikeyには空文字が入る。
let apikey = "";
$.get('/my/account').done(function(data){
     apikey = $("#api-access-key", $(data)).first().text();
});

// Redmine 3.1以降版。専用ページなので読み込み負荷は若干低いはず。
// REST APIのON/OFFに関わらずapikeyにはAPIキーの文字列が入る。
let apikey = "";
$.get('/my/api_key').done(function(data){
    apikey = $('#content > div.box > pre', $(data)).first().text();
});

REST APIの実行

RedmineのAPIリファレンスを参考にしながら、ajax等でREST APIを叩く。

Redmine API

$.ajax({
    type: 'get',
    url: '/issues/7.json',
    data: {include:'relations'},
    headers: {'X-Redmine-API-Key': apikey},
    dataType: 'text',
    contentType: 'application/json',
})
.done((strJson) => console.log(JSON.parse(strJson)))

簡単にapikeyの取得とREST APIを続けて書くなら以下のようになるだろうか。

$.get('/my/account')
.then(
    // マイページをスクレイピングしてapikeyを取得
    (html) => {
        return $("#api-access-key", $(html)).first().text();
    }
)
.then(
    // REST APIでチケット詳細を取得
    (apikey) => {
        return $.ajax({
            type: 'get',
            url: '/issues/15780.json',
            data: {include:'relations'},
            headers: {'X-Redmine-API-Key': apikey},
            dataType: 'text',
            contentType: 'application/json',
        });
    }
)
.then(
    // 取得したチケット情報を表示
    (json) =>  console.log(json)
)

雑感

最初はapikeyを入力させるダイアログを作成し、Web Storage経由でapikeyを各画面で使い回す方法も考えた。
しかしRedmineの内部フックを使っているわけではないため、ログアウトしても前のユーザーのapikeyが残ってしまうのはセキュリティ的にかなりよくない。

(REST APIでアクセスできるデータを調べると分かるが、ユーザーのアクセス権限内ならばほぼ全てのデータを大量に読み書きできてしまう)

そこで多少"黒魔術"的ではあるしアクセス負荷が余計にかかるが、個人設定ページをスクレイピングしてapikeyを取得し使い捨てる方法を考えた。
これならクッキーにもWeb Storageにも残らず、個人ページをブラウザで開いてコピペするのと同じ処理になる。

22
18
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?