【Apex】別ユーザーでエクスペリエンスにログインしたことを検知したい

# はじめに
この記事では、Experience Cloudにログインしているユーザーが``ユーザーとしてエクスペリエンスにログイン``でログインしているユーザーかどうかを見分ける方法を解説します。
調べてなかなか出てこなかったので誰かの役に立てばいいなーという気持ちで書きます。

# そもそも調べたきっかけ
Salesforceで開発している中でクライアントから``ユーザーとしてエクスペリエンスにログイン``した場合は処理を制限してほしいと言われたことがきっかけです。

Experience Cloudに通常通りログインしているユーザーに関してはできる処理も、``ユーザーとしてエクスペリエンスにログイン``しているユーザーに関してはできないようにしなければいけないとなったときにいろいろ調べた結果この内容にたどり着きました。

# 本題
見分け方に関しては**SessionManagement クラス**の**getCurrentSession メソッド**取得される下記4つを注意してみてみれば判別できます。
``LoginHistoryId == null``
``LoginType != null``
``SourceIp = '::'``
``UserType = 'Standard'``

Apexで例を記載して説明します。

```apex 
Map<String,String> currentSessionMap = Auth.SessionManagement.getCurrentSession();
System.debug('currentSessionMap:'+currentSessionMap);
Boolean isLogCommunityAsUser = false;
if(currentSessionMap.get('LoginHistoryId') == null && currentSessionMap.get('LoginType') != null &&
    currentSessionMap.get('SourceIp') == '::' && currentSessionMap.get('UserType') == 'Standard'){
    isLogCommunityAsUser=true;
}
System.debug('実際のユーザーは"ユーザーとしてエクスペリエンスにログイン"を使用してログインしています : ' + isLogCommunityAsUser);
```
``ユーザーとしてエクスペリエンスにログイン``を使用してログインした場合のデバッグは下記のようになります。
```
//デバッグ内容
currentSessionMap : {
    UsersId = 0055i00000AuHEoAAN,
    Username = test@test.com,
    SessionType = ChatterNetworks,
    UserType = Standard,
    LoginType = Unknown,
    SourceIp = ::,
    SessionSecurityLevel = STANDARD,
    SessionId = 0Ak5i0000GE9YnkCQF,
    ParentId = 0Ak5i0000GE9co6CQB,
    LogoutUrl = null,
    LoginDomain = test.my.site.com,
    LoginHistoryId = null,
    LoginGeoId = null,
    CreatedDate = Sun Nov 05 12:06:48 GMT 2023,
    LastModifiedDate = Sun Nov 05 12:06:47 GMT 2023,
    NumSecondsValid = 7200
}
実際のユーザーは"ユーザーとしてエクスペリエンスにログイン"を使用してログインしています : true
```
通常通りユーザ名、パスワードでログインした場合のデバッグは下記のようになります。
※一部内容を非表示にしています[^1]
[^1]: IPアドレス
```
//デバッグ内容
currentSessionMap : {
    UsersId = 0055i00000AuHEoAAN,
    Username = test@test.com,
    SessionType = ChatterNetworks,
    UserType = CspLitePortal,
    LoginType = Chatter Communities External User,
    SourceIp = ************,
    SessionSecurityLevel = STANDARD,
    SessionId = 0Ak5i0000GECJAjCQP,
    ParentId = null,
    LogoutUrl = null,
    LoginDomain = test.my.site.com,
    LoginHistoryId = 0Ya5i00003zb4jiCAA,
    LoginGeoId = 04F5i00003tB9aBEAS,
    CreatedDate = Sun Nov 06 02:16:18 GMT 2023,
    LastModifiedDate = Sun Nov 06 02:16:18 GMT 2023,
    NumSecondsValid = 7200
}
実際のユーザーは"ユーザーとしてエクスペリエンスにログイン"を使用してログインしています : false
```

## 結論
**SessionManagement クラス**の**getCurrentSession メソッド**取得される下記4つを注意してみてみれば判別できます。
``LoginHistoryId == null``
``LoginType != null``
``SourceIp = '::'``
``UserType = 'Standard'``

~~正直``LoginHistoryId == null``だけ確認すればいい気もしますが、、、~~

何かしら``ユーザーとしてエクスペリエンスにログイン``を検知して処理を分けたい場合、下記のコードを参考に実装できるかと思います。
よかったら参考にしてみてください！

```Apex
Map<String,String> currentSessionMap = Auth.SessionManagement.getCurrentSession();
Boolean isLogCommunityAsUser = false;
if(currentSessionMap.get('LoginHistoryId') == null && currentSessionMap.get('LoginType') != null &&
    currentSessionMap.get('SourceIp') == '::' && currentSessionMap.get('UserType') == 'Standard'){
    isLogCommunityAsUser=true;
}
if(isLogCommunityAsUser){
    //ユーザーとしてエクスペリエンスにログインしている場合の処理
}else{
    //通常通りユーザー名、パスワードでログインしている場合の処理
}
```

下記にSessionManagement クラスのApex 開発者ガイドを張っておきます。
気になる方は確認してみてください！

https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_class_Auth_SessionManagement.htm