実現したいこと
JavascriptでMicrosoft Entra ID(旧Azure AD)認証を行いトークンを取得したいと考えております。
発生している問題・分からないこと
リダイレクトURIが表示されるところまでいきますが、URLに付加されているパラメータが取得できないため、その先の処理に進めません。ソースコード内の「urlParams = new URLSearchParams(window.location.search);」の処理がうまくいっていないようです。
該当のソースコード
Javascript
1// Azure AD アプリケーションの情報を設定 2const CLIENT_ID = "XXXXXX"; // アプリケーション (クライアント) ID 3const TENANT_ID = "XXXXXX"; // テナントID 4const REDIRECT_URI = "https://xxx.com/"; // リダイレクトURI 5const CLIENT_SECRET = "XXXXXX"; // クライアントシークレット(本番環境ではここで代入させない) 6 7const SCOPES = "User.Read"; // 必要なスコープ 8 9// エンドポイント 10const AUTHORIZATION_ENDPOINT = `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/authorize`; 11const TOKEN_ENDPOINT = `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token`; 12 13// DOM 要素の取得 14const signInButton = document.getElementById("signInButton"); 15const tokenDisplay = document.getElementById("tokenDisplay"); 16 17// サインインボタンのクリックイベント 18signInButton.addEventListener("click", () => { 19 initiateLogin(); 20}); 21 22// ログインフローを開始 23function initiateLogin() { 24 const state = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); // CSRF対策用のstate 25 sessionStorage.setItem('oauth_state', state); // stateをセッションストレージに保存 26 27 const authUrl = new URL(AUTHORIZATION_ENDPOINT); 28 authUrl.searchParams.append("client_id", CLIENT_ID); 29 authUrl.searchParams.append("response_type", "code"); // 認証コードフロー 30 authUrl.searchParams.append("redirect_uri", REDIRECT_URI); 31 authUrl.searchParams.append("scope", SCOPES); 32 authUrl.searchParams.append("state", state); 33 authUrl.searchParams.append("response_mode", "query"); // クエリパラメータでコードを返す 34 35 window.location.href = authUrl.toString(); // Azure AD の認証ページにリダイレクト 36} 37 38// ページロード時の処理 39window.onload = () => { 40 const urlParams = new URLSearchParams(window.location.search); 41 const code = urlParams.get("code"); 42 const state = urlParams.get("state"); 43 const error = urlParams.get("error"); 44 const storedState = sessionStorage.getItem('oauth_state'); 45 46 if (error) { 47 tokenDisplay.textContent = `認証エラー: ${error} - ${urlParams.get("error_description")}`; 48 console.error("認証エラー:", error, urlParams.get("error_description")); 49 return; 50 } 51 52 if (code && state && state === storedState) { 53 // 認証コードと state が存在し、state が一致する場合 54 sessionStorage.removeItem('oauth_state'); // stateを削除 55 getAccessToken(code); 56 } else if (code && state && state !== storedState) { 57 tokenDisplay.textContent = "CSRF攻撃の可能性: stateが一致しません。"; 58 console.error("State mismatch. Potential CSRF attack."); 59 } else { 60 // 通常のページロード時、何も処理しない 61 console.log("初期ページロードまたは認証コードなし"); 62 } 63}; 64 65// アクセストークンの取得 66async function getAccessToken(code) { 67 68 const params = new URLSearchParams(); 69 params.append("client_id", CLIENT_ID); 70 params.append("scope", SCOPES); 71 params.append("code", code); 72 params.append("redirect_uri", REDIRECT_URI); 73 params.append("grant_type", "authorization_code"); 74 params.append("client_secret", CLIENT_SECRET); // クライアントシークレットを含める 75 76 try { 77 const response = await fetch(TOKEN_ENDPOINT, { 78 method: "POST", 79 headers: { 80 "Content-Type": "application/x-www-form-urlencoded", 81 }, 82 body: params.toString(), 83 }); 84 85 if (!response.ok) { 86 const errorData = await response.json(); 87 throw new Error(`トークン取得エラー: ${response.status} - ${errorData.error_description || JSON.stringify(errorData)}`); 88 } 89 90 const data = await response.json(); 91 console.log("アクセストークン取得成功:", data); 92 tokenDisplay.textContent = `アクセストークン:\n${data.access_token}\n\nIDトークン:\n${data.id_token || "なし"}\n\nリフレッシュトークン:\n${data.refresh_token || "なし"}`; 93 94 // リフレッシュトークンが必要な場合は、ここで保存するなどして利用 95 // (ただし、ブラウザのLocalStorage等に直接保存するのはセキュリティリスクがあるため注意) 96 97 } catch (error) { 98 console.error("トークン取得エラー:", error); 99 tokenDisplay.textContent = `トークン取得エラー: ${error.message}`; 100 } 101}
html
1<!DOCTYPE html> 2<html> 3<head> 4 <title>Azure AD 認証 (MSALなし)</title> 5</head> 6<body> 7 <h1>Azure AD 認証サンプル (MSALなし)</h1> 8 <button id="signInButton">サインイン</button> 9 <pre id="tokenDisplay"></pre> 10 11 <script src="app.js"></script> 12</body> 13</html>
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
ネットで検索していろいろ試してみましたが、うまくいきませんでした。
<追記:20250806>
consoleを見たところ403エラーが出ているため、window.onload内の処理が行われていないことが判明しました。
補足
特になし

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/08/06 03:52
2025/08/06 04:21 編集
2025/08/06 05:53
2025/08/07 03:59
2025/08/08 01:52
2025/08/12 00:28
2025/08/12 00:49
2025/08/13 02:43
2025/08/13 03:46
2025/08/13 06:17