指導教學: 在階段作業中間鑑別使用者
如果您已啟用 Web 會談安全,則必須在階段作業開始時設定客戶的使用者 ID,作為您用來簽署訊息的「JSON Web 記號 (JWT)」的一部分。 對於未經鑑別的使用者,這通常是產生的 ID,且在建立 JWT 之後無法變更。 不過,您可以稍後在階段作業中使用專用變數來鑑別使用者。
在啟用 Web 會談安全的情況下,與每一則訊息相關聯的使用者 ID 是根據 JWT 有效負載中的 sub 要求。 當建立 JWT 時,必須在階段作業開始時設定此值,且在階段作業生命期間無法變更。 對於未經鑑別 (匿名) 的使用者,您通常會使用所產生的 ID (儲存至 Cookie),以確保每一個唯一客戶基於計費目的僅計數一次。
不過,您可能希望客戶能夠在階段作業期間進行鑑別 (例如,完成更新使用者帳戶資訊的動作)。 因為無法變更在 sub 聲明中產生的使用者 ID,您需要另一種方式來安全地鑑別使用者。 作法是將客戶的實際已鑑別使用者 ID 儲存為 JWT 使用者有效負載中的專用變數。 (您可以將使用者 ID 儲存在一般環境定義變數中,但這並不安全,因為這類變數可以修改。)
如需本指導教學中所說明範例的完整工作版本,請參閱 啟用 watsonx Assistant Web 會談(複式)的安全。
如需具有最低程式碼來啟用安全的 Web 會談版本 (在階段作業期間沒有已加密的有效負載及使用者變更),請參閱 啟用 watsonx Assistant Web 會談的安全(簡式)。
本指導教學中的這個範例是以 Express Server for Node.js為基礎,顯示如何以匿名使用者 ID 來啟動階段作業,然後在階段作業期間鑑別使用者。
-
建立稱為
getOrSetAnonymousID()的函數,為每一個客戶產生唯一匿名使用者 ID,並將它儲存在 Cookie 中 (如果 Cookie 已存在,則會使用儲存的使用者 ID)。請使用至少持續 45 天的 Cookie。 如果您沒有儲存使用者 ID 超過 30 天,在相同的計費期間,相同的客戶可能會被視為多個不同的使用者。 (如果相同的使用者刪除 Cookie 或使用不同的瀏覽器,仍會發生這種情況。)
function getOrSetAnonymousID(request, response) {
let anonymousID = request.cookies['ANONYMOUS-USER-ID'];
if (!anonymousID) {
anonymousID = `anon-${uuid()}`;
}
response.cookie('ANONYMOUS-USER-ID', anonymousID, {
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 45), // 45 days.
httpOnly: true,
});
return anonymousID;
}
-
在您用來建立 JWT 的函數中,使用從
getOrSetAnonymousID()函數傳回的匿名 ID 作為sub要求的值。 這會設定使用者 ID 的值,該使用者 ID 將用來唯一識別客戶以進行計費。此外,請從
SESSION_INFOCookie 中擷取任何值,以用來儲存已鑑別的登入資訊。 如果值存在,請將它儲存在 JWT 的user_payload專用要求中。 (如果使用者尚未鑑別,則此 Cookie 尚未存在。)
const jwtContent = {
sub: anonymousUserID,
user_payload: {
name: 'Anonymous',
custom_user_id: anonymousUserID,
},
};
if (sessionInfo) {
jwtContent.user_payload.name = sessionInfo.userName;
jwtContent.user_payload.custom_user_id = sessionInfo.customUserID;
}
- 建立函數以處理使用者鑑別。 在我們的範例中,我們使用簡式
authenticate()函數來設定寫在程式中的使用者 ID,但在實際應用程式中,在安全鑑別檢查之後,可能會從資料庫擷取使用者 ID。 將使用者資訊儲存在SESSION_INFOCookie 中。
function authenticate(request, response) {
const userInfo = {
userName: 'Cade',
customUserID: 'cade-id',
};
response.cookie('SESSION_INFO', JSON.stringify(userInfo), { encode: String });
response.send('Ok');
}
-
當使用者登入時,請呼叫
authenticate()函數,將使用者資訊儲存在SESSION_INFOCookie 中。 然後呼叫createJWT()函數,以使用更新的階段作業資訊來移入user_payload要求,以重新產生 JWT。在 我們的範例中,按一下簡單按鈕即可模擬鑑別。 相同的按鈕也會透過刪除 Cookie 來模擬登出:
async function onClick() { if (getCookieValue('SESSION_INFO')) { document.cookie = 'SESSION_INFO=; Max-Age=0'; } else { await fetch('http://localhost:3001/authenticate'); } const result = await fetch('http://localhost:3001/createJWT'); const newToken = await result.text(); webChatInstance.updateIdentityToken(newToken); updateUI(); }sub要求中的匿名 ID 將繼續用來追蹤客戶以進行計費,但現在客戶的實際使用者 ID 會個別儲存在使用者有效負載中。 -
在您的動作中,您現在可以參照
user_payload專用環境定義變數來存取客戶的實際使用者 ID:
${system_integrations.chat.private.user_payload}.custom_user_id
如需完整的工作程式碼,請參閱 啟用 watsonx Assistant Web 會談的安全 範例。
如果您需要符合 GDPR 需求,則可能需要持續儲存任何產生的匿名使用者 ID,特別是對於稍後以使用者認證登入的匿名使用者。 儲存這些使用者 ID 可讓您稍後刪除與個別客戶相關聯的所有資料 (如果要求這樣做的話)。