OutSystemsでログイン後にもともとアクセスしていたページを開く

作成したばかりのTraditionalWebモジュールでは、あるページへのアクセス後に（ログインページに自動遷移し）ログインすると、トップページへ遷移してしまいます。
これが不便な場合、改修を行うことで、もともとアクセスしていたページヘ遷移させることも可能です。

# サンプル
https://www.outsystems.com/forge/Component_Overview.aspx?ProjectId=7064
NoPermission screenのPreparationの一番下部分です。

# 環境
Personal Environment(Version 11.7.3 (Build 5968))
Service Studio(Version 11.6.31)

# デフォルトでの動作の仕組み
改修の方針を立てるために、まずは作成したTraditionalWebモジュールにデフォルトで備わっている仕組みを確認してみます。権限の必要な画面にアクセス→ログイン画面に遷移→ログイン後トップページへ遷移を実現している仕組みです。

## 全体像
![qReturnAfterLogin1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/3e32d6f4-dd4c-1d26-1b29-93a0c893f51e.png)
この画像につけた説明の通り、以下の順番で処理が行われ、結果的に（モジュールの）トップページに遷移します。
1. 未ログインのまま権限が必要な画面にアクセス
2. 権限がないため、Security Exceptionが発生し、Global Exception Handlerで処理
3. Security Exception発生後はNoPermission画面へ自動遷移
4. 未ログインかつ統合認証未使用なら、Login画面へ自動遷移(このとき、モジュールトップページのURLが、パラメータとして渡される)
5. Login画面でログインを実行すると、渡されたURLへ遷移する

## Security Exception
未ログインのまま権限が必要な画面にアクセスしたとき、またはログイン中だが画面が要求するロールをユーザーがもっていないとき、Security ExceptionがOutSystemsによって発生させられます。

標準の仕組みの場合、Global Exception Handler(Common UI FlowのOnException Actionが設定されている)にHandlerが配置されています。このHandlerはそのままNoPermission画面へ遷移させます。

## NoPermission画面
状態と設定に応じて、適切な画面へつなぐ画面です。画面としての中身は持っていません。
未ログインの場合は、図の中で赤枠で囲んだLogin画面へ自動的に遷移します。
このとき、組込関数の「GetOwnerURLPath()」でモジュールのURLを取得してLogin画面のパラメータに渡す仕組み。

## Login画面
この画面でログインを実行すると、ExternalURLを使ってパラメータで指定されたパスへ自動で遷移させられます。

このとき、ExternalURLに渡されるURLは以下の式で決定します。

`If(ReplaceURLDomain(OriginalURL) = "", GetOwnerURLPath(), ReplaceURLDomain(OriginalURL))`

つまり、パラメータが渡されればそのURLへ、渡されなかった場合も結局GetOwnerURLPath()へ（つまりモジュールのトップページへ）移動することになります。

# 改修（ログイン後、もともとアクセスしていたページへ戻る）

## 改修箇所
発生している現象＝ログイン後に「モジュールのトップページ」に遷移するに対応する「GetOwnerURLPath()」を呼んでいる箇所を直せばいいですね。

Login画面を直接開くケースがありえます。その場合にはログイン実行後に、現在の処理の通り、モジュールのトップページへ遷移するのがいいですね。そこで、Loginはそのままにし、NoPermissionからLoginを開く場所を修正しましょう。

## もともとアクセスしていたページを取得する方法
OutSystemsに含まれているAPIにいくつかURLを取得するためのものがあるため、実験しながらどれを使うか検討してみます。

オリジナルのアクセス先
　https://<ホスト>/HousesoftSampleTraditional/ReturnAfterLogin.aspx?MandatoryInput=abcd

対してアクセスして、デバッガで確認してみました。

| Module | Action | 結果 |
|:--|:--|:--|
| HTTPRequestHandler | GetURL | https://<ホスト>/HousesoftSampleTraditional/ReturnAfterLogin.aspx?MandatoryInput=abcd |
| HTTPRequestHandler | GetReferrerURL |  |
| HTTPRequestHandler | GetRawURL | /HousesoftSampleTraditional/ReturnAfterLogin.aspx?MandatoryInput=abcd |
| URL(組込) | GetBookmarkableURL | https://<ホスト>/HousesoftSampleTraditional/NoPermission.aspx |

GetURLかGetRawURLがよさそうです。違いは

- GetRawURLはhttp(s)://ホストの部分が含まれない相対パス
- ドキュメントによるとSEO URLs適用時の挙動が違う
    - [GetURL](https://success.outsystems.com/Documentation/11/Reference/OutSystems_APIs/HTTPRequestHandler_API#GetURL)：SEO URLsによって変換された後のURLが返る
    - [GetRawURL](https://success.outsystems.com/Documentation/11/Reference/OutSystems_APIs/HTTPRequestHandler_API#GetRawURL)：SEO URLsによって変換される前のユーザーのブラウザーに表示されるURLが返る

NoPermissionからLoginに渡すパラメータのURLは相対パスで問題ありません。
というわけで、実際にユーザーがリクエストした相対パスを返すGetRawURLを使うのが良さそうです。

## 修正
NoPermissionのPreparationを以下のように修正しました。
Login遷移前にGetRawURLを呼び、その結果をLogin画面のOriginalURLに渡すようにしています。
![qReturnAfterLogin2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/a4b7ff87-9882-85b3-1cb7-466c556db170.png)