【Redmine 6.1以降対応】REST API OAuth2の使い方:設定手順とコード例

 •  分類:  •  本村真一

Redmine 6.1 から、REST API において OAuth2 による認証が公式にサポートされました。

これまでのAPIキー方式に加え、業界標準の認可プロトコルであるOAuth2が利用可能になったことで、外部システムとの連携をより安全かつ柔軟に管理できるようになります。

本記事では、OAuth2導入のメリットから、Redmine上での設定手順、そしてRubyを用いたサンプルコードを示します。APIを通じてRedmineのチケット数を取得するRubyスクリプトを紹介します。

目次

  1. APIキーからOAuth2へ:なぜ移行が必要なのか
  2. OAuth2導入による2つのメリット
  3. RedmineでのOAuth2設定手順
  4. Rubyによる実装例(APIキー vs OAuth2)
  5. まとめ
  6. 参考リンク

1. APIキーからOAuth2へ:なぜ移行が必要なのか

従来の「APIキー」は、手軽に利用できる反面、セキュリティ面でいくつかの課題がありました。

  • 権限の制御が困難: APIキーはユーザーの全権限を代行するため、特定の操作(例:チケットの閲覧のみ)に限定することが困難でした。
  • 鍵の漏洩時の影響が大きい: 複数のツールで同じキーを使い回すことが多く、一つのツールで漏洩が発生すると、そのユーザーの全連携を停止・再設定する必要がありました。

2. OAuth2導入による2つのメリット

Redmine 6.1のOAuth2対応は、これらの課題を解決します。

  1. スコープ(Scope)による最小権限の原則: 「チケットの閲覧のみ(view_issues)」など、アプリケーションに必要な最小限の権限だけを許可できます。
  2. トークン形式による安全性: ユーザーの認証情報(パスワードやAPIキー)をアプリ側に渡す必要がありません。また、有効期限付きの「アクセストークン」と、それを更新する「リフレッシュトークン」を用いることで、万が一の漏洩リスクを最小化できます。

3. RedmineでのOAuth2設定手順

「REST APIを通じてRedmineのチケット数を取得するRubyスクリプトを実行する」を題材として、OAuth2を利用するための設定手順を解説します。

OAuth2を利用するには、まずRedmine側で「アプリケーション」を登録する必要があります。
※ この操作には「システム管理者」権限が必要です。

3.1 アプリケーションの登録

  1. 「管理」 → 「アプリケーション」 へ移動します。もし「アプリケーション」が表示されていない場合は、 REST APIを有効にする必要があります。REST API(Redmine用語解説)を参考にして「RESTによるWebサービスを有効にする」にチェックを入れてください。なお、ブログ内の解説では、現在の「連携」タブが「API」と表記されている箇所がございます。適宜読み替えてください。
  2. 「新しいアプリケーション」 をクリックし、必要な情報を入力します。

    アプリケーションの名前、リダイレクトURIの入力
  3. アプリケーションに許可する権限(Scope)を選択します。
    • 「名前」: 連携するアプリケーションを識別できる名前(例: Ruby Issue Monitor)
    • 「リダイレクトURI」: 認証後にリダイレクトされるURL。スクリプトやデスクトップアプリの場合は urn:ietf:wg:oauth:2.0:oob を入力します。
    • 「Scopes」: アプリに許可する操作(例: view_issues)にチェックを入れます。Redmine上の各権限がスコープとして定義されています。スクリプト等のアプリを作成する際は、実装する機能に合わせて必要なスコープを選択してください。なお、スクリプト等のアプリを作成する際に、実際に利用するスコープを宣言する必要があります。

      権限をチェック
  4. 「保存」 をクリックします。

3.2 認証情報の取得

登録完了後、アプリケーションの詳細画面が表示されます。 画面に表示される 「アプリケーションID」「シークレット」 を安全な場所に控えてください。これらはスクリプトなどで使用します。


アプリケーション作成後の画面

4. Rubyによる実装例(APIキー vs OAuth2)

ここでは、Rubyを使用してチケットの件数を取得する2つのパターンを紹介します。
簡単なサンプルコードのため、チケットの件数は正確ではありません。
以下のサンプルコードでは、あらかじめ次のような .env ファイルを作成して使用します。

# REDMINE_SITE_URL にはアクセス先のRedmineのURLをセットする
REDMINE_SITE_URL=https://redmine.example.jp/

##### APIキーを用いるサンプルコード用 #####

REDMINE_API_KEY=xxxxx

##### OAuth2を用いるサンプルコード用 #####

# REDMINE_APPLICATION_ID と REDMINE_CLIENT_SECRET には
# Redmineでアプリケーション作成後に表示された「アプリケーションID」と
# 「シークレット」の値をセットする
REDMINE_APPLICATION_ID=xxxxxx
REDMINE_CLIENT_SECRET=xxxxx
REDMINE_CALLBACK_URL=urn:ietf:wg:oauth:2.0:oob
REDMINE_TOKEN_FILE=redmine_token.json

4.1 従来のAPIキーを用いる場合

require 'net/http'
require 'uri'
require 'json'
require 'dotenv'

# .envファイルから環境変数を読み込み
Dotenv.load

SITE_URL = ENV.fetch('REDMINE_SITE_URL')
API_KEY = ENV.fetch('REDMINE_API_KEY')

begin
  uri = URI("#{SITE_URL}/issues.json")
  request = Net::HTTP::Get.new(uri)

  # 従来の認証:ヘッダーにAPIキーをセット
  request["X-Redmine-API-Key"] = API_KEY

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
    http.request(request)
  end

  if response.code.to_i == 200
    issues = JSON.parse(response.body)
    puts "成功! チケット総数: #{issues['total_count']}件"
  else
    puts "APIエラー: #{response.code}"
  end

rescue => e
  puts "予期せぬエラーが発生しました: #{e.message}"
end

4.2 新しいOAuth2を用いる場合

OAuth2認証では、Redmineへの接続に「アクセストークン」を使用します。アクセストークンには有効期限があるため、期限切れのたびに手動で認可をやり直すのは現実的ではありません。 そこで、失効時に「リフレッシュトークン」を用いてトークンを自動更新する仕組みを導入します。以下のサンプルコードでは、この更新処理を効率的に実装できる oauth2ライブラリを利用しています。 なお、以下のサンプルコードでは環境変数 TOKEN_FILE で指定されたファイル(前述の .env ファイルでは redmine_token.json )にアクセストークンとリフレッシュトークンを保存する実装になっています。このファイルはパスワードと同等の価値があるため、 .gitignore に追加してリポジトリに含めないようするなど、実際の利用時には運用管理に十分注意してください。

require 'oauth2'
require 'json'
require 'dotenv'

Dotenv.load

# 設定の読み込み
APPLICATION_ID     = ENV.fetch('REDMINE_APPLICATION_ID')
CLIENT_SECRET = ENV.fetch('REDMINE_CLIENT_SECRET')
SITE_URL      = ENV.fetch('REDMINE_SITE_URL')
CALLBACK_URL  = ENV.fetch('REDMINE_CALLBACK_URL')
TOKEN_FILE    = ENV.fetch('REDMINE_TOKEN_FILE')

SCOPE = 'view_issues'

# OAuth2クライアントの初期化
client = OAuth2::Client.new(
  APPLICATION_ID, CLIENT_SECRET,
  site: SITE_URL,
  authorize_url: SITE_URL + '/oauth/authorize',
  token_url: SITE_URL + '/oauth/token'
)

def save_token(token)
  File.write(TOKEN_FILE, JSON.generate(token.to_hash))
end

# 有効なトークンを取得・管理するメソッド
def get_valid_token(client)
  if File.exist?(TOKEN_FILE)
    token = OAuth2::AccessToken.from_hash(client, JSON.parse(File.read(TOKEN_FILE)))

    # 期限切れなら自動でリフレッシュ
    if token.expired?
      return token.refresh!.tap { |t| save_token(t) }
    end
    return token
  end

  # 初回認可フロー
  puts "初回認証が必要です。ブラウザで承認してコードを入力してください。"
  puts client.auth_code.authorize_url(redirect_uri: CALLBACK_URL, scope: SCOPE)
  print "\nCode: "
  code = gets.chomp
  client.auth_code.get_token(code, redirect_uri: CALLBACK_URL).tap { |t| save_token(t) }
end

begin
  token = get_valid_token(client)

  response = token.get('/issues.json')

  if response.status == 200
    issues = JSON.parse(response.body)
    puts "成功! チケット総数: #{issues['total_count']}件"
  else
    puts "APIエラー: #{response.status}"
  end

rescue => e
  puts "予期せぬエラーが発生しました: #{e.message}"
end

スクリプト実行時の流れ

初回実行時、コンソールには以下のようなメッセージが表示されます。

初回認証が必要です。ブラウザで承認してコードを入力してください。
https://redmine.example.jp/oauth/authorize?client_id=xxxxx&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=view_issues

Code:

表示されたURLをブラウザで開くと、認可画面が表示されます。この際、URLを開いたユーザーの権限に基づいてトークンが生成されるため、適切な権限を持つユーザーでログインして承認を行う必要があります。


認可許可を要求する画面

「承認」ボタンを押すと、認可コードが表示されます。


認可コードを表示している画面

このコードをコンソールの Code: 欄に貼り付けることで、アクセストークンが発行され、APIの実行が可能になります。

4.3 実行結果の確認

APIキー方式とOAuth2方式、どちらを用いてもリクエストが成功すれば同じ結果が得られます。スクリプトを実行すると、以下のようにRedmineから取得したデータが表示されます(以下はチケット件数を取得した際の例です)。

成功! チケット総数: 2件

5. まとめ

Redmine 6.1 の OAuth2 対応は、APIを利用した自動化スクリプトや連携アプリケーションの信頼性を一段階引き上げるアップデートです。特に複数のプロジェクトや外部ツールを運用している環境では、セキュリティと管理の効率化の両面で大きな恩恵があります。

従来のAPIキー方式からOAuth2への移行を、この機会にぜひ検討してみてください。

作成: 2026-02-03 16:00  •  分類: