0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

freeeAPIを使うためのOAuth認証を理解してみた

0
Last updated at Posted at 2025-08-23

1. OAuth認証についてなぜ調べたか

普段は経理の業務を行っています。

業務ではまだ使ったことがないのですが、前から freee会計 に興味がありました。

今回、ポートフォリオ用に「freee APIを使ったWebアプリ」を作ろうと思い、まずは事前調査として OAuth認証 についてまとめます。

freee APIを利用するためには、最初にOAuth認証でアクセストークンを取得する必要があります。

今回は「PHPでアクセストークンを取得して、companies APIを叩く」まで学習のために行ったので

下記、学習過程で調べたことを備忘録としてまとめます。


2. OAuth認証

freee APIは OAuth 2.0 認証 を使っています。

OAuth 2.0とは、他のサービスと安全に連携し、ユーザーがログインや認可を行うための仕組みです。

(例:GoogleログインなどもOAuthの仕組みを使っています)

OAuth2認証の仕組みで知っておくこと

役割 説明
リソースオーナー freee にログインするユーザー(例:経理担当者)
クライアント 自分が作るアプリ(PHP)
認可サーバー 認可コードやトークンを発行(https://accounts.secure.freee.co.jp/...
リソースサーバー 実際のデータを返すAPIサーバー(https://api.freee.co.jp/api/1/...

freee APIの場合は以下の流れになります:

  1. ユーザーが freee 認可サーバーの画面にアクセス
  2. ログインして、アプリにアクセス許可を与える
  3. freee 認可サーバー → アプリ(リダイレクトURL)に「認可コード」を返す
  4. アプリ(サーバー側コード)が、その認可コードを freee 認可サーバー に渡してアクセストークンを取得
  5. アクセストークンを使って freee のリソースサーバー(APIサーバー)を呼び出す

freee APIの流れについて参考にしました

公式ドキュメントに認証フローの図があるので参考に


開発環境

Docker Compose で PHP + MySQL を動かす環境を用意しました。構成は以下の通りです。

  • Docker を利用して構築

  • サービス構成

    • app コンテナ

      • ベースイメージ: php:8.2-cli

      • インストール済みライブラリ:

        • PHP拡張: pdo, pdo_mysql, zip
        • 開発用: xdebug
        • composer(composer:2 イメージからコピー)
      • 開発用サーバ: php -S 0.0.0.0:8000 -t src

      • ポート: 8000 番をホストに公開 (http://localhost:8000)

      • .env を読み込む設定あり (env_file: .env)

    • db コンテナ

      • イメージ: mysql:8.0
      • ポート: 3306
      • 永続化: db_data ボリューム
      • 初期設定
  • ボリューム

    • db_data → MySQL データ永続化用
  • その他

    • Xdebug 設定済み(リモートデバッグ用)
    • composer でパッケージ管理 (vlucas/phpdotenv など利用可)

3. 手順メモ(実際にやったこと)

(1) freee 開発者コンソールでアプリを登録

  • client_idclient_secret を取得
  • redirect_uri を設定(例: http://localhost/callback.php

freee_api_image3.png

(2) 認可コードを取得してみる

開発アプリを作成したらアプリ詳細設定にあるWebアプリ認証用URLにアクセスすると、freeeのログイン画面が表示されます:

freee_api_image1.png

認証が成功すると、リダイレクトURLに ?code=xxxxx が付与されます。

freee_api_image2.png

(3) 認可コード → アクセストークンに交換(PHPサンプル)

今回の検証では、まずシンプルに index.php → callback.php で認証〜API呼び出しまで試しました。

freee API には PHP 向けの公式リファレンスはないようなので、ChatGPT に相談したところ、PHP では curl などのライブラリを使って HTTP リクエストを送り、JSON を扱う方法があるとわかりました。

具体的な流れとしては、freee API の公式リファレンスに記載されている JSON 構造を、そのまま curl の POST ボディに渡す形になります。PHP では json_encode($data) で同じ形式に変換して送信し、返ってきたレスポンスも JSON なので、json_decode($response, true) を使って連想配列に変換して処理します。

最初は動くものを試して理解したかったのでサンプルコードをChatGPTに作ってもらい、自分の環境に合わせてIDやURLを.envファイルで設定しました。

下記、ChatGPTに作成してもらったコードです。

index.php

<?php
// ----- 設定 -----
$client_id = "ClientID";
$redirect_uri = "callback.php のURL";
$state = bin2hex(random_bytes(16)); // CSRF対策

// ----- 認可URL生成 -----
$url = "https://accounts.secure.freee.co.jp/public_api/authorize?" . http_build_query([
    "response_type" => "code",
    "client_id" => $client_id,
    "redirect_uri" => $redirect_uri,
    "state" => $state,
    "prompt" => "select_company"
]);

// ----- ユーザーを認可画面にリダイレクト -----
header("Location: $url");
exit;

callback.php

<?php
// ----- 設定 -----
$client_id = "自分のClientID";
$client_secret = "自分のClientSecret";
$redirect_uri = "http://localhost/callback.php";

if (!isset($_GET['code'])) {
    die("認可コードがありません");
}

$code = $_GET['code'];

// ----- アクセストークン取得 -----
$token_url = "https://accounts.secure.freee.co.jp/public_api/token";

$data = [
    "grant_type" => "authorization_code",
    "client_id" => $client_id,
    "client_secret" => $client_secret,
    "code" => $code,
    "redirect_uri" => $redirect_uri,
];

$options = [
    "http" => [
        "header"  => "Content-Type: application/x-www-form-urlencoded\r\n",
        "method"  => "POST",
        "content" => http_build_query($data),
    ],
];

$context  = stream_context_create($options);
$response = file_get_contents($token_url, false, $context);

if ($response === FALSE) {
    die("アクセストークン取得失敗");
}

$token_info = json_decode($response, true);
$access_token = $token_info['access_token'];

// ----- 事業所情報を取得 -----
$company_url = "https://api.freee.co.jp/api/1/companies";

$opts = [
    "http" => [
        "header" => "Authorization: Bearer $access_token",
        "method" => "GET"
    ]
];

$context2 = stream_context_create($opts);
$company_response = file_get_contents($company_url, false, $context2);

if ($company_response === FALSE) {
    die("事業所情報取得失敗");
}

$company_data = json_decode($company_response, true);

// ----- 画面表示 -----
echo "<h2>アクセストークン</h2>";
echo "<p>{$access_token}</p>";

echo "<h2>事業所情報</h2>";
echo "<pre>";
print_r($company_data);
echo "</pre>";

実行結果

  • ブラウザで index.php にアクセスすると freee の認可画面に遷移
  • 認可後 callback.php に戻り、アクセストークンが取得できる
  • さらに、 companies API を叩いて事業所情報が取得できた

freee_api_image4.png

(6) 環境変数で管理する例

.env に以下を記述:

FREEE_CLIENT_ID=自分のClientID
FREEE_CLIENT_SECRET=自分のClientSecret
FREEE_REDIRECT_URI=アクセス先

4. ハマったポイント

  • freeeの会計APIリファレンスを読んでも最初は仕組みがよくわからなかった
  • 特に「アクセストークンってどう取るの?」が大きな壁でした

参考記事

これらの記事を参考にしつつ、自分の環境で動作するコードをChatGPTに作成してもらい調整しました。


まとめ

  • freee APIを使うには、まず OAuth 2.0 認証フロー を理解することが大事。
    特に「認可コード → アクセストークン → API呼び出し」という流れを理解しておくと全体像がつかみやすい。

  • アクセストークンを取得する際に重要なのは、以下の 4つの要素 を正しく設定すること:

    • client_id(アプリを識別するためのID)
    • client_secret(アプリの秘密鍵)
    • grant_type(利用するフローの種類。今回は authorization_code
    • redirect_uri(コールバックURL)(認可後にコードが返されるURL)
  • 仕組みとして覚えておくべきは次の 3ステップ

    1. 認可コードを取得する
    2. 認可コードをアクセストークンに交換する
    3. アクセストークンを使ってAPIを呼び出す

さいごに

curl などを使うのは初めてだったので良い学びになりましたが、自分で処理を組み立てる必要があるため、実務では使われているのか疑問を持ちました。また、curl以外にもGuzzleというライブラリを使う方法があると後でわかったので、今後試したいと思います。

0
1
0

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?