Adobe Experience Manager as a Cloud Service のクロスオリジンリソース共有(CORS)は、AEM 以外の web プロパティが、AEM の GraphQL API およびその他の AEM ヘッドレスリソースに対してブラウザーベースのクライアントサイド呼び出しを容易に行えるようにします。
設定例は次のようになります。プロジェクトの要件に合わせて調整してください。
AEM に接続するクライアントが AEM と同じオリジン(ホストまたはドメインとも呼ばれる)から提供されない場合、AEM GraphQL API へのブラウザーベースの接続には、CORS が必要です。
クライアントタイプ | シングルページアプリ(SPA) | Web コンポーネント/JS | モバイル | サーバー間 |
---|---|---|---|---|
CORS 設定が必要 | ✔ | ✔ | ✘ | ✘ |
AEM オーサーサービスでの CORS の有効化は、AEM パブリッシュサービスおよび AEM プレビューサービスの場合とは異なります。AEM オーサーサービスでは、OSGi 設定を AEM オーサーサービスの実行モードフォルダーに追加する必要があり、Dispatcher 設定は使用しません。
AEM CORS OSGi 設定ファクトリは、CORS HTTP リクエストを受け入れるための許可条件を定義します。
クライアントの接続先 | AEM オーサー | AEM パブリッシュ | AEM プレビュー |
---|---|---|---|
CORS OSGi 設定が必要 | ✔ | ✘ | ✘ |
次の例は、AEM オーサーの OSGi 設定(../config.author/..
)を定義し、AEM オーサーサービス上でのみアクティブです。
主な設定プロパティは次のとおりです。
alloworigin
や alloworiginregexp
は AEM web に接続するクライアントの実行元を指定します。allowedpaths
は指定したオリジンから許可される URL パスパターンを指定します。
/graphql/execute.json.*
」を追加します。/content/experience-fragments/.*
」を追加します。supportedmethods
は、CORS リクエストで許可される HTTP メソッドを指定します。 AEM GraphQL 永続クエリ(およびエクスペリエンスフラグメント)をサポートするには、GET
を追加します。"Authorization"
を含む supportedheaders
は、認証を受ける必要があります。true
に設定されている supportscredentials
は、認証を受ける必要があります。CORS OSGi の設定について詳しくは、こちらを参照してください。
次の例では、 AEM オーサーでの AEM GraphQL 永続クエリの使用をサポートしています。クライアント定義の GraphQL クエリを使用するには、allowedpaths
および POST
からの GraphQL エンドポイント URL を supportedmethods
に追加します。
/ui.config/src/main/content/jcr_root/apps/wknd-examples/osgiconfig/config.author/com.adobe.granite.cors.impl.CORSPolicyImpl~graphql.cfg.json
{
"alloworigin":[
"https://spa.external.com/"
],
"alloworiginregexp":[
],
"allowedpaths": [
"/graphql/execute.json.*",
"/content/experience-fragments/.*"
],
"supportedheaders": [
"Origin",
"Accept",
"X-Requested-With",
"Content-Type",
"Access-Control-Request-Method",
"Access-Control-Request-Headers",
"Authorization"
],
"supportedmethods":[
"GET",
"HEAD",
"POST"
],
"maxage:Integer": 1800,
"supportscredentials": true,
"exposedheaders":[ "" ]
}
AEM パブリッシュ(およびプレビュー)サービスで CORS を有効にすることは、AEM オーサーサービスとは異なります。AEM パブリッシュサービスでは、AEM Dispatcher 設定を AEM パブリッシュの Dispatcher 設定に追加する必要があります。AEM パブリッシュは、OSGi 設定を使用しません。
AEM パブリッシュで CORS を設定する際には、次の点を確認します。
Origin
HTTP リクエストヘッダーは、AEM Dispatcher プロジェクトの clientheaders.any
ファイルから Origin
ヘッダー(以前に追加されていた場合)を削除すると、AEM パブリッシュサービスに送信できなくなります。Access-Control-
ヘッダーは、clientheaders.any
ファイルから削除する必要があり、AEM パブリッシュサービスではなく Dispatcher がこれらを管理します。AEM パブリッシュ(およびプレビュー)サービスの Dispatcher は、CORS をサポートするように設定する必要があります。
クライアントの接続先 | AEM オーサー | AEM パブリッシュ | AEM プレビュー |
---|---|---|---|
Dispatcher の CORS 設定が必要 | ✘ | ✔ | ✔ |
Dispatcher 設定プロジェクトで、AEM パブリッシュサービスの vhost 設定ファイルを開きます。通常は、dispatcher/src/conf.d/available_vhosts/<example>.vhost
にあります。
以下の <IfDefine ENABLE_CORS>...</IfDefine>
ブロックの内容を、有効な vhost 設定ファイルにコピーします。
<VirtualHost *:80>
...
<IfModule mod_headers.c>
################## Start of CORS configuration ##################
SetEnvIfExpr "req_novary('Origin') == ''" CORSType=none CORSProcessing=false
SetEnvIfExpr "req_novary('Origin') != ''" CORSType=cors CORSProcessing=true CORSTrusted=false
SetEnvIfExpr "req_novary('Access-Control-Request-Method') == '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != ''" CORSType=invalidpreflight CORSProcessing=false
SetEnvIfExpr "req_novary('Access-Control-Request-Method') != '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != ''" CORSType=preflight CORSProcessing=true CORSTrusted=false
SetEnvIfExpr "req_novary('Origin') -strcmatch '%{REQUEST_SCHEME}://%{HTTP_HOST}*'" CORSType=samedomain CORSProcessing=false
# For requests that require CORS processing, check if the Origin can be trusted
SetEnvIfExpr "%{HTTP_HOST} =~ /(.*)/ " ParsedHost=$1
################## Adapt regex to match CORS origin(s) for your environment
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*\.your-domain\.tld(d+?lang=ja)?$)#" CORSTrusted=true
# Extract the Origin header
SetEnvIfNoCase ^Origin$ ^(.*)$ CORSTrustedOrigin=$1
# Flush If already set
Header unset Access-Control-Allow-Origin
Header unset Access-Control-Allow-Credentials
# Trusted
Header always set Access-Control-Allow-Credentials "true" "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Allow-Origin "%{CORSTrustedOrigin}e" "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Allow-Methods "GET" "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Max-Age 1800 "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Allow-Headers "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers" "expr=reqenv('CORSTrusted') == 'true'"
# Non-CORS or Not Trusted
Header unset Access-Control-Allow-Credentials "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
Header unset Access-Control-Allow-Origin "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
Header unset Access-Control-Allow-Methods "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
Header unset Access-Control-Max-Age "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
# Always vary on origin, even if its not there.
Header merge Vary Origin
# CORS - send 204 for CORS requests which are not trusted
RewriteCond expr "reqenv('CORSProcessing') == 'true' && reqenv('CORSTrusted') == 'false'"
RewriteRule "^(.*)" - [R=204,L]
# Remove Origin before sending to AEM Publish if this configuration handles the CORS
RequestHeader unset Origin "expr=reqenv('CORSTrusted') == 'true'"
################## End of CORS configuration ##################
</IfModule>
...
</VirtualHost>
以下の行の正規表現を更新して、AEM パブリッシュサービスにアクセスする目的の接触チャネルと一致させます。複数の接触チャネルが必要な場合は、この行を複製し、接触チャネル/接触チャネルパターンごとに更新します。
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*.your-domain.tld(:\d+)?$)#" CORSTrusted=true
例えば、接触チャネルからの CORS アクセスを有効にするには:
https://example.com
の任意のサブドメインhttp://localhost
上の任意のポートこの行を次の 2 行に置き換えます。
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*\.example\.com$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(http://localhost(:\d+)?$)#" CORSTrusted=true