Twitterを見ていたら、このツィートへのKris Riceの返信として、ORDSのRESTfulサービスでOracle APEXのセッションを引き継げるとコメントしていました。
これは初耳だったので、自分でも確認してみました。
こちらの記事 - Oracle APEXでWebコンポーネント扱う - で作成したRESTfulサービスを保護した上で、アプリケーションを改変してみます。
RESTfulサービスの保護
RESTfulサービス自体はサンプルのoracle.example.hrです。このモジュールを対象として権限を追加します。マニュアルの記載箇所はこちらです。
SQLワークショップよりRESTfulサービスを開いて、左ペインのツリーから権限を選択します。右側のペインにORDSの権限として、一覧ページが表示されます。権限の作成を実行します。
名前、タイトルは任意です。ここではそれぞれ、名前をモジュール名と同じoracle.example.hr、タイトルをHR Accessとしています。
ロールとして、RESTful Servicesを選択します。そして、保護されたモジュールとして、oracle.example.hrを選択し、権限を作成します。
以上でRESTfulサービスの保護は完了です。
最初の例題で使用しているORDSテンプレート定義(employees/)の完全なURLを確認し、そのURLをブラウザから呼び出して、保護の状態を確認します。
URLにアクセスすると、401 Unauthrized が返されます。
アプリケーションの改変
保護されたRESTfulサービスへアクセスする際に、HTTPヘッダーとしてApex-Sessionを与えます。形式は以下です。
Apex-Session: アプリケーションID,セッションID
Webコンポーネントの記事で作成したアプリケーションをアプリケーション・ビルダーで開き、共有コンポーネントの静的アプリケーション・ファイルを開きます。Edit Filesより、すでに作成済みのemployee-info.jsを選択します。
fetchの部分を、リクエストのヘッダーとしてApex-Sessionを含めるよう、以下に変更します。
fetch('https://apex.oracle.com/pls/apex/あなたのWS/hr/employees/' + this.getAttribute('empno'), { "method": "GET", "headers": { "Apex-Session": this.getAttribute('appid') + "," + this.getAttribute('sessid') } } )
アプリケーションIDおよびセッションIDは、employee-info要素の属性のappid、sessidとして渡します。
静的コンテンツのソースには、以下のようにappid、sessidを追加します。
<employee-info empno="7839" appid="&APP_ID." sessid="&APP_SESSION."></employee-info>
動的アクションの記載は、以下のようにappid、sessidを追加します。
以上でアプリケーション側の変更も完了です。アプリケーションを実行すると、RESTfulサービスを保護する以前と同様に動作することが確認できます。
最後にKris Riceが、以下のSQLを実行していました。
select :current_user from dual
引き渡されたOracle APEXのセッションの認証ユーザー名(APP_USERに該当)が:current_userで取得できるとのこと。結果を見るとユーザー名が小文字になっていて、大抵の場合、大文字だけになるOracle APEX側のAPP_USER置換文字列とは若干異なるもようです。この点は要注意です。
完