この記事では、エンジニア初心者向けにwebAPIの認証方式について、解説していきたいと思います。
自社のアプリケーションからサードパーティーのリソースにAPI経由でアクセスする際は、基本的にリクエストヘッダーに認証情報を含める必要があります。
APIを使用したいのに、認証の仕方が分からないエンジニア初心者の方向けに代表的な認証方式について、仕組みやサンプルコードを解説します。
webAPIの基礎知識
webAPIとは
WebAPIは、ウェブ上で異なるアプリケーション同士が情報をやり取りするための手段です。これは、異なるプログラムやサービスが互いに通信し、データを共有することが可能になります。具体的には、外部の開発者やプログラムが、特定のサービスやデータにアクセスできるようにするプログラミングのインターフェースです。
例えば、天気情報のサービスが提供しているWebAPIを利用すると、他のアプリケーションやウェブサイトがその天気情報を取得できるようになります。これによって、異なるアプリケーション同士が連携し、より豊富で柔軟な機能を提供することが可能となります。
WebAPIは、HTTPプロトコルを通じてデータを受け渡しすることが一般的で、JSONやXMLなどのデータ形式を使用します。これにより、クロスプラットフォームでの統一的なデータのやり取りが可能となり、異なるプログラミング言語やプラットフォームでも利用できる汎用性があります。
webAPIの認証とは
WebAPIの認証は、APIを利用する際に正当なユーザーであることを確認し、セキュリティを確保するための手続きです。認証は、アクセストークンやキーなどの情報を用いて行われ、これにより悪意ある利用や不正なアクセスを防ぎます。提供されるサービスにより、認証方式が異なるので、利用サービスのAPIリファレンスを参照の元、構築してください。
webAPIの認証方式の代表的なものには、以下があります。
以下で書く認証方式について、詳しく解説します。JavascriptのfetchAPIのサンプルコードも記載しています。
Basic認証
Basic認証の仕組みとメリット
Basic認証は、HTTPプロトコルにおいて最もシンプルな認証方式の一つです。
クライアントがサーバーにAPIリクエストを実行する際に、ヘッダーのAuthorizationの値に、ユーザー名とパスワードをBase64でエンコードした文字列を設定します。
サーバー側は、上記の文字列からユーザー名とパスワードが認証システムに登録された情報と一致するか検証します。正しい場合は、リクエストが許可されレスポンスが返却されます。
ただし、Basic認証は通信が平文でやり取りされ、Base64でエンコードした文字列も簡単にデコードできてしまうため、セキュリティ要件に応じて利用を検討する必要があります。
Basic認証のサンプルコード
const url = "https://api.example.com/data";
const username = "your_username";
const password = "your_password";
// ユーザー名とパスワードをBase64エンコード
const base64Credentials = btoa(`${username}:${password}`);
// ヘッダーにAuthorizationを追加
const headers = new Headers({
Authorization: `Basic ${base64Credentials}`,
"Content-Type": "application/json", // レスポンスがJSON形式であることを示す
});
// GETリクエストを送信
fetch(url, {
method: "GET",
headers: headers,
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error("Fetch error:", error));
btoa
関数を使用してユーザー名とパスワードをBase64エンコードし、それをAuthorizationヘッダーに含めています。
// ユーザー名とパスワードをBase64エンコード
const base64Credentials = btoa(`${username}:${password}`);
token認証
token認証の仕組みとメリット
token認証は、認証情報としてトークンを使用する仕組みです。一般的には、ユーザーが認証された後に発行されたトークンを使用してアクセスを許可します。
トークンには認証情報を直接含まないためユーザー名やパスワードが漏洩しても直接の影響を受けません。セキュリティが向上します
token認証のサンプルコード
const url = "https://api.example.com/data";
const accessToken = "your_access_token";
// ヘッダーにAuthorizationを追加
const headers = new Headers({
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json", // レスポンスがJSON形式であることを示す
});
// GETリクエストを送信
fetch(url, {
method: "GET",
headers: headers,
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error("Fetch error:", error));
ヘッダー情報に、Bearer アクセストークンを含めてAPIリクエストを投げます。token認証はOAuth2.0のフローの中でも使用される仕組みです。
// ヘッダーにAuthorizationを追加
const headers = new Headers({
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json", // レスポンスがJSON形式であることを示す
});
APIキー認証
APIキー認証の仕組みとメリット
APIキー認証は、簡単な認証手段の一つで、APIにアクセスする際に特定のキー(APIキー)を使用して認証を行います。API利用者は単にキーをリクエストに含めるだけでアクセスできます
APIプロバイダーは、API利用者に対して一意のAPIキーを発行します。このキーは通常、ダッシュボードや管理コンソールから取得できます。APIキーはユーザーの個別の認証情報とは独立しており、APIのアクセス権を管理するための独自の仕組みとして扱われます。
各リクエストにはキーが含まれているため、APIプロバイダーは利用者ごとにリソース使用量をトラッキングしやすくなります。ただし、APIキー認証はセキュリティ上のリスクを伴います。キーが漏洩した場合、第三者が不正にAPIにアクセスする可能性があるため、HTTPSを使用して通信を暗号化するなどの対策が必要です。
APIキー認証のサンプルコード
const url = "https://api.example.com/data";
const apiKey = "your_api_key_here";
// ヘッダーにAPIキーを追加
const headers = new Headers({
"X-API-Key": apiKey,
"Content-Type": "application/json", // レスポンスがJSON形式であることを示す
});
// GETリクエストを送信
fetch(url, {
method: "GET",
headers: headers,
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error("Fetch error:", error));
このコードでは、APIキーを"X-API-Key"
というヘッダーに含めています。your_api_key_here
の部分には実際のAPIキーを代入する必要があります
// ヘッダーにAPIキーを追加
const headers = new Headers({
"X-API-Key": apiKey,
"Content-Type": "application/json", // レスポンスがJSON形式であることを示す
});
OAuth認証
OAuth認証の基本的な仕組み
OAuthは、ユーザーが他のWebサービスやアプリケーションにアクセス権を付与するための仕組みを提供します。これにより、ユーザーは自分の資格情報(ユーザー名とパスワード)を直接共有せずに、外部サービスにアクセスできるようになります。
OAuth 2.0の主なフロー
1.認可コードグラント(Authorization Code Grant)フロー
このフローは、Webアプリケーションやサーバーサイドのアプリケーション向けに設計されています。ユーザーがクライアントアプリケーションに対してアクセス権を与えるため、認可コードを介して行われます。
①クライアントアプリケーションがリダイレクトURIとクライアントID、スコープを指定して認可エンドポイントにリクエストを送信します。
②リソースオーナーに認可の意思を確認します
③リソースオーナーは認可サーバーにログインし、クライアントにアクセス権を与えるか拒否します。
const authorizationEndpoint = 'https://authorization-server.com/authorize';
const params = {
response_type: 'code',
client_id: 'CLIENT_ID',
redirect_uri: 'REDIRECT_URI',
scope: 'SCOPE',
state: 'STATE',
};
const authorizationUrl = `${authorizationEndpoint}?${new URLSearchParams(params)}`;
// ブラウザでリダイレクト
window.location.href = authorizationUrl;
response_type=code
はAuthorization Code Grantを使用することを示します。
④認可が成功すると、認可コードがリダイレクトURIに返されます。
REDIRECT_URI?code=AUTHORIZATION_CODE&state=STATE
⑤クライアントアプリケーションは認可コードとクライアントシークレットを使用してトークンエンドポイントにリクエストを送信します
const tokenEndpoint = 'https://authorization-server.com/token';
const tokenParams = {
grant_type: 'authorization_code',
code: 'AUTHORIZATION_CODE',
redirect_uri: 'REDIRECT_URI',
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET',
};
fetch(tokenEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams(tokenParams),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Token request error:', error));
⑥アクセストークンを取得します
{
"access_token": "ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN",
"scope": "SCOPE"
}
⑦アクセストークンを利用して、リソースサーバーへアクセスします
const resourceEndpoint = 'https://api.example.com/resource';
const accessToken = 'YOUR_ACCESS_TOKEN';
// POSTリクエストのデータ(例:JSON形式)
const postData = {
key1: 'value1',
key2: 'value2',
};
// ヘッダーにアクセストークンを追加
const headers = new Headers({
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
});
// POSTリクエストを送信
fetch(resourceEndpoint, {
method: 'POST',
headers: headers,
body: JSON.stringify(postData),
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => console.log('Response:', data))
.catch(error => console.error('Fetch error:', error));
2.インプリシットグラント(Implicit Grant)フロー
このフローは、クライアントアプリケーションがサーバーサイドでのトークン取得が不要なシンプルな場合に使用されます(JavaScriptやモバイルアプリなど)。
Implicit Grantはセキュリティ上の脆弱性が指摘されており、Authorization Code Grantが推奨されています
アクセストークンが直接リダイレクトURIに含まれます。
①クライアントアプリケーションがリダイレクトURIとクライアントID、スコープを指定して認可エンドポイントにリクエストを送信します。
②リソースオーナーに認可の意思を確認します
③リソースオーナーは認可サーバーにログインし、クライアントにアクセス権を与えるか拒否します。
const authorizationEndpoint = 'https://authorization-server.com/authorize';
const params = {
response_type: 'token',
client_id: 'CLIENT_ID',
redirect_uri: 'REDIRECT_URI',
scope: 'SCOPE',
state: 'STATE',
};
const authorizationUrl = `${authorizationEndpoint}?${new URLSearchParams(params)}`;
// ブラウザでリダイレクト
window.location.href = authorizationUrl;
response_type=token
はImplicit Grantを使用することを示します。
④認可が成功すると、アクセストークンが直接リダイレクトURIに返されます。
REDIRECT_URI#access_token=ACCESS_TOKEN&token_type=bearer&expires_in=3600&scope=SCOPE&state=STATE
⑤アクセストークンを利用して、リソースサーバーへアクセスします
3.クライアントクレデンシャルズ(Client Credentials)フロー
このフローは、クライアントアプリケーションがユーザーの代わりにリソースにアクセスする場合に使用されます。
①クライアントアプリケーションがクライアント資格情報(クライアントID、クライアントシークレットID)を使用してトークンエンドポイントにリクエストを送信します。
const tokenEndpoint = 'https://authorization-server.com/token';
const tokenParams = {
grant_type: 'client_credentials',
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET',
scope: 'SCOPE',
};
fetch(tokenEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams(tokenParams),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Token request error:', error));
②認可サーバーはクライアント資格情報を検証し、アクセストークンを返します。
{
"access_token": "ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "SCOPE"
}
アクセストークンを利用して、リソースサーバーへアクセスします
まとめ
初心者エンジニアがWebAPI認証を理解するためには、まず基本的な概念を掴むことが重要です。APIキー、Bearerトークン、Basic認証などの認証手法の違いや、セキュリティ意識を持ちHTTPSを使用するなどの基本的な実装手順を学ぶことがポイントです。例えば、APIキーは単純ながら有効で、BearerトークンはOAuthに基づく柔軟性があります。フローの理解と実際のサンプルコードで手を動かすことで、認証の基礎を築けます。