세션 및 권한 관리
플레이어와 부모가 동의 흐름을 완료한 후(VPC 위젯 또는 커스텀 연령 게이트를 통해), 게임은 플레이어의 권한을 포함하는 세션을 받습니다. 그러나 권한은 시간이 지나면서 변경될 수 있습니다: 부모가 Family Connect를 통해 설정을 조정하거나, 플레이어가 생일을 맞아 새로운 연령 카테고리로 이동하거나, 누군가가 추가 기능에 대한 액세스를 요청할 수 있습니다.
이 가이드는 이러한 변경 사항을 감지하고, 적절하게 대응하며, 플레이어에게 명확하게 전달하여 항상 현재 기능 액세스를 이해할 수 있도록 하는 방법을 설명합니다.
게임이 닫혀 있는 동안(또는 실행 중에도) 권한이 변경되면 기능이 갑자기 나타나거나 사라질 수 있어 플레이어가 혼란스러워할 수 있습니다. 명확한 전달이 없으면 이러한 변경 사항이 버그처럼 보일 수 있으며, 부모의 의도적인 업데이트나 연령 관련 조정으로 보이지 않을 수 있습니다.
사전 요구 사항
시작하기 전에 다음을 확인하세요:
- 완료된 동의 흐름: 플레이어는 VPC 빠른 시작 또는 커스텀 연령 게이트 빠른 시작을 완료하여 활성 세션이 있어야 합니다
- k-ID 제품: k-ID Compliance Studio에서 제품 생성 및 구성
- API 키: Compliance Studio의 제품 개발자 설정 페이지에서 API 키 생성
- 웹훅 엔드포인트 (권장): 세션 이벤트를 받을 보안 HTTPS 엔드포인트 설정. 자세한 내용은 웹훅을 참조하세요.
세션 및 Challenge 이해
플레이어가 신뢰할 수 있는 성인으로부터 액세스 권한을 부여받으면, 제품당 정확히 하나의 세션을 갖게 됩니다. 권한이 변경되면(부모 수정, 연령 증가 이벤트 또는 권한 업그레이드를 통해) 동일한 세션 ID가 새로운 권한으로 업데이트됩니다. 새로운 세션이 생성되지 않습니다. 기존 세션이 플레이어의 액세스 현재 상태를 반영합니다. 그러나 세션이 취소되고 신뢰할 수 있는 성인이 동의 흐름을 다시 거치면 새로운 세션 ID를 가진 새 세션이 생성됩니다.
Challenge는 부모 승인이 필요한 동의 요청입니다. Challenge가 성공적으로 완료되면(PASS) 세션이 생성되거나 부여된 권한으로 업데이트됩니다. 반대로 세션이 삭제되면 해당 플레이어의 모든 미완료 Challenge가 자동으로 FAIL로 설정됩니다. Challenge에 대한 자세한 정보는 Challenges 개념 가이드를 참조하세요.
권한이 변경될 수 있는 방법
권한 변경은 여러 이유로 발생할 수 있습니다:
| 변경 유형 | 설명 | 감지 방법 |
|---|---|---|
| 부모가 권한 수정 | 부모가 Family Connect를 사용하여 기능을 활성화하거나 비활성화 | 웹훅 또는 세션 비교 |
| 플레이어 연령 증가 | 생일로 인해 플레이어가 새로운 연령 카테고리로 이동. 플레이어가 더 이상 부모 동의가 필요하지 않은 연령에 도달하면 권한의 managedBy가 PLAYER로 설정되어 부모 동의 없이 플레이어가 직접 제어할 수 있게 됩니다 | 세션 비교만 |
| 세션 삭제 | 부모가 Family Connect를 통해 액세스를 취소하여 세션이 삭제됨(400 반환) | 웹훅 또는 세션 비교(400 반환) |
이러한 시나리오를 이해하면 올바른 감지 전략을 구현하는 데 도움이 됩니다.
1단계: 감지 접근 방식 선택
권한 변경을 감지하는 두 가지 접근 방식이 있습니다. 대부분의 구현에서는 웹훅을 기본 방법으로 사용하고 세션 비교를 대체 방법으로 사용하여 둘 다 사용해야 합니다.
접근 방식 A: 웹훅 기반 감지 (권장)
HTTP 콜백을 받을 수 있는 서버가 있는 경우 웹훅을 사용하세요.
이 접근 방식에서는 부모가 권한을 변경하면 k-ID가 즉시 서버에 알립니다. 서버가 자체 상태를 업데이트하고 게임은 다음 시작 시 또는 기능 액세스 시 업데이트된 상태를 읽습니다.
장점:
- 변경 감지에 지연이 없는 실시간 알림
- 지속적인 폴링보다 리소스 사용량이 적음
- 플레이어에게 사전 알림 가능
작동 방식:
접근 방식 B: 재시작 시 세션 비교
웹훅이 없거나 웹훅과 함께 대체 방법으로 사용하는 경우 세션 비교를 사용하세요.
이 접근 방식에서는 게임이 마지막으로 알려진 세션을 캐시하고 각 재시작 시(또는 게임플레이 중 주기적으로) k-ID의 현재 세션과 비교합니다.
장점:
- 웹훅 구성이 필요 없음
- 연령 증가 변경 사항을 포착(웹훅을 트리거하지 않음)
- 구현이 간단함
작동 방식:
2단계: 웹훅 기반 감지 구현
게임에 서버가 있는 경우 실시간 권한 업데이트를 위해 웹훅 기반 감지를 구현합니다.
모든 k-ID API 호출은 클라이언트 측 코드가 아닌 서버에서 수행해야 합니다. API 키를 게임 클라이언트에 노출해서는 안 됩니다. 이 가이드의 예제는 서버 측 코드(Node.js 및 Express)를 보여줍니다. 게임 클라이언트는 자체 서버와 통신한 다음 서버가 k-ID API를 호출합니다.
웹훅 엔드포인트 구성
Compliance Studio에서 제품의 개발자 설정 아래에 웹훅 URL을 구성합니다. 엔드포인트가 다음을 받을 수 있는지 확인하세요:
Session.ChangePermissions: 부모가 권한을 변경할 때 발생Session.Delete: 세션이 삭제될 때 발생
Session.ChangePermissions 웹훅 처리
k-ID가 이 웹훅을 발생시키면 서버 상태를 업데이트하여 세션이 변경되었음을 플래그로 표시합니다:
app.post("/webhook/k-id", (req, res) => {
const { eventType, data } = req.body;
switch (eventType) {
case "Session.ChangePermissions":
// Flag this session as having changed permissions
markSessionAsChanged(data.id, {
changeType: "permissions_updated",
changedAt: new Date().toISOString()
});
break;
case "Session.Delete":
// Parent revoked access - session has been deleted
// Note: All incomplete challenges for this player are automatically set to FAIL
markSessionAsDeleted(data.id);
break;
}
res.status(200).send("OK");
});
권한 가져오기 및 비교
게임 클라이언트가 서버에 연결하면 변경 플래그를 확인하고 k-ID에서 업데이트된 세션을 가져와 저장된 버전과 비교하여 변경된 내용을 확인합니다:
// Server-side endpoint that your game client calls
app.get("/api/check-permissions/:sessionId", async (req, res) => {
const { sessionId } = req.params;
const changeInfo = await getChangeFlag(sessionId);
if (!changeInfo.hasChanged) {
return res.json({ hasChanged: false });
}
const cachedSession = await getStoredSession(sessionId);
const response = await fetch(
`https://game-api.k-id.com/api/v1/session/get?sessionId=${sessionId}`,
{ headers: { "Authorization": `Bearer ${process.env.KID_API_KEY}` } }
);
const { session: newSession } = await response.json();
const changes = comparePermissions(cachedSession, newSession);
await storeSession(sessionId, newSession);
await clearChangeFlag(sessionId);
res.json({
hasChanged: true,
changes: changes,
session: newSession
});
});
comparePermissions 함수(3단계에서 표시)는 정확히 어떤 권한이 변경되었는지 식별하여 플레이어에게 특정 메시지를 표시할 수 있게 합니다.
3단계: 세션 비교 구현
대체 방법(또는 웹훅이 없는 경우 기본 방법)으로 세션 비교를 구현합니다. 이 접근 방식은 웹훅을 트리거하지 않는 연령 증가 변경을 감지하는 데도 필수적입니다.
Session.ChangePermissions 웹훅은 권한이 변경되었다는 사실을 알려주지만 무엇이 변경되었는지는 포함하지 않습니다. 어떤 특정 권한이 활성화되었거나 비활성화되었는지 확인하려면 업데이트된 세션을 가져와 캐시된 버전과 비교해야 합니다. 이 비교 로직은 웹훅 또는 폴링을 사용하는지 여부에 관계없이 필요합니다.
세션 저장
세션을 받을 때마다 서버에 저장합니다(데이터베이스, 캐시 또는 플레이어와 연결된 기타 영구 저장소에):
// Server-side session storage
async function storeSession(sessionId, session) {
await db.sessions.upsert({
sessionId: sessionId,
session: session,
updatedAt: new Date().toISOString()
});
}
async function getStoredSession(sessionId) {
const record = await db.sessions.findOne({ sessionId });
return record?.session || null;
}
게임 시작 시 세션 비교
게임 클라이언트가 시작되면 서버를 호출하여 세션 변경 사항을 확인해야 합니다. 서버는 k-ID에서 현재 세션을 가져와 비교합니다:
// Server-side endpoint that your game client calls on startup
app.get("/api/session/:sessionId", async (req, res) => {
const { sessionId } = req.params;
const cachedSession = await getStoredSession(sessionId);
if (!cachedSession) {
return res.json({ needsConsent: true });
}
const response = await fetch(
`https://game-api.k-id.com/api/v1/session/get?sessionId=${sessionId}&etag=${cachedSession.etag}`,
{ headers: { "Authorization": `Bearer ${process.env.KID_API_KEY}` } }
);
if (response.status === 304) {
return res.json({ hasChanged: false, session: cachedSession });
}
const { session: currentSession } = await response.json();
const changes = comparePermissions(cachedSession, currentSession);
await storeSession(sessionId, currentSession);
res.json({
hasChanged: changes.length > 0,
changes: changes,
session: currentSession
});
});
권한 차이 감지
이전 세션과 새 세션을 비교하여 특정 변경 사항을 식별합니다:
function comparePermissions(oldSession, newSession) {
const changes = [];
for (const newPerm of newSession.permissions) {
const oldPerm = oldSession.permissions.find(p => p.name === newPerm.name);
if (!oldPerm) {
changes.push({ type: "added", permission: newPerm.name, enabled: newPerm.enabled });
} else if (oldPerm.enabled !== newPerm.enabled) {
changes.push({
type: newPerm.enabled ? "enabled" : "disabled",
permission: newPerm.name,
previousState: oldPerm.enabled
});
} else if (oldPerm.managedBy !== newPerm.managedBy) {
changes.push({
type: "management_changed",
permission: newPerm.name,
previousManagedBy: oldPerm.managedBy,
newManagedBy: newPerm.managedBy
});
}
}
if (oldSession.ageStatus !== newSession.ageStatus) {
changes.push({
type: "age_status_changed",
previousStatus: oldSession.ageStatus,
newStatus: newSession.ageStatus
});
}
return changes;
}
플레이어가 연령이 증가하여 더 이상 부모 동의가 필요하지 않게 되면 k-ID는 웹훅 알림을 보내지 않습니다. 그러나 세션을 비교하면 이전에 managedBy: "GUARDIAN"이었던 권한이 managedBy: "PLAYER"로 변경되었음을 알 수 있습니다.
권한이 플레이어 관리가 되면 플레이어는 부모 동의 없이 직접 제어할 수 있습니다. 부모에게 요청하는 대신 플레이어가 직접 이러한 권한을 활성화하거나 비활성화할 수 있도록 UI를 업데이트해야 합니다. 플레이어가 /session/upgrade API를 통해 PLAYER 관리 권한을 활성화하도록 요청하면 Challenge를 생성하지 않고 자동으로 활성화됩니다. 4단계의 updateFeatureAccess 함수는 UI에서 PLAYER 관리 권한을 처리하는 방법을 보여줍니다.
4단계: 변경 사항을 플레이어에게 전달
변경 사항을 감지하면 기능이 변경된 이유를 플레이어에게 명확하게 전달합니다. 이것이 중요합니다: 플레이어가 무언가가 고장났다고 생각해서는 안 됩니다.
권한 변경 사항을 전달하고, 비활성화된 기능을 표시하며, 권한 요청을 처리하는 방법에 대한 자세한 디자인 권장 사항은 UX 가이드라인을 참조하세요.
정보 제공 대화 상자 표시
클라이언트 측에서 무엇이 변경되었는지, 왜 변경되었는지 설명하는 대화 상자를 표시합니다(서버에서 반환된 changes 배열 사용):
function showPermissionChangeDialog(changes) {
const disabledFeatures = changes
.filter(c => c.type === "disabled")
.map(c => getFeatureDisplayName(c.permission));
const enabledFeatures = changes
.filter(c => c.type === "enabled")
.map(c => getFeatureDisplayName(c.permission));
const ageChanged = changes.find(c => c.type === "age_status_changed");
let message = "";
if (ageChanged) {
// Player aged up
message = "Happy birthday! 🎉 Your permissions have been updated based on your new age.";
} else if (disabledFeatures.length > 0 && enabledFeatures.length === 0) {
// Parent restricted features
message = "Your parent has updated your permissions. " +
"The following features are no longer available:\n\n" +
disabledFeatures.map(f => `• ${f}`).join("\n");
} else if (enabledFeatures.length > 0 && disabledFeatures.length === 0) {
// Parent enabled features
message = "Great news! Your parent has enabled new features:\n\n" +
enabledFeatures.map(f => `• ${f}`).join("\n");
} else {
// Mixed changes
message = "Your permissions have been updated.";
if (enabledFeatures.length > 0) {
message += "\n\nNow available:\n" + enabledFeatures.map(f => `• ${f}`).join("\n");
}
if (disabledFeatures.length > 0) {
message += "\n\nNo longer available:\n" + disabledFeatures.map(f => `• ${f}`).join("\n");
}
}
showDialog({
title: "Permissions Updated",
message: message,
buttons: [{ text: "OK", action: "dismiss" }]
});
}
function getFeatureDisplayName(permissionName) {
const displayNames = {
"voice-chat": "Voice Chat",
"text-chat-private": "Private Messages",
"text-chat-public": "Public Chat",
"in-game-purchases": "In-Game Purchases",
"multiplayer": "Online Multiplayer",
// Add all your permissions here
};
return displayNames[permissionName] || permissionName;
}
비활성화된 기능을 적절하게 처리
클라이언트 측에서 기능이 비활성화된 경우 UI가 이를 명확하게 반영하도록 합니다(서버에서 반환된 세션 데이터 사용):
function updateFeatureAccess(session) {
for (const permission of session.permissions) {
const featureElement = document.querySelector(`[data-feature="${permission.name}"]`);
if (!featureElement) continue;
if (!permission.enabled) {
featureElement.classList.add("feature-disabled");
if (permission.managedBy === "GUARDIAN") {
// Show "Ask parent" option
featureElement.setAttribute("data-disabled-reason", "parent");
featureElement.querySelector(".disabled-message").textContent =
"Ask a parent to enable this feature";
} else if (permission.managedBy === "PROHIBITED") {
// Feature is not available in this jurisdiction
featureElement.setAttribute("data-disabled-reason", "prohibited");
featureElement.querySelector(".disabled-message").textContent =
"This feature is not available";
} else if (permission.managedBy === "PLAYER") {
featureElement.setAttribute("data-disabled-reason", "player-choice");
featureElement.querySelector(".disabled-message").textContent = "Tap to enable";
featureElement.addEventListener("click", () => togglePlayerPermission(permission.name));
}
} else {
featureElement.classList.remove("feature-disabled");
if (permission.managedBy === "PLAYER") {
featureElement.setAttribute("data-managed-by", "player");
}
}
}
}
managedBy가 PLAYER인 경우 플레이어는 부모 동의 없이 권한을 직접 제어할 수 있습니다. 이는 일반적으로 플레이어가 연령이 증가한 후에 발생합니다. 플레이어가 이러한 권한을 활성화하거나 비활성화할 수 있는 토글 및 버튼과 같은 UI 컨트롤을 제공해야 합니다. 플레이어가 /session/upgrade API를 통해 PLAYER 관리 권한을 활성화하도록 요청하면 Challenge를 생성하지 않고 자동으로 활성화됩니다(부모 동의가 필요하지 않음).
5단계: 세션 삭제 처리
부모가 Family Connect를 통해 플레이어의 제품에 대한 모든 액세스를 취소하면 세션이 최종 단계로 삭제됩니다. 세션은 단순히 사라집니다: 쿼리는 HTTP 400을 반환합니다. 이것이 발생하면(웹훅 또는 세션 비교 중에 감지) 플레이어는 액세스를 다시 얻기 위해 연령 게이트 및 동의 흐름을 다시 완료해야 합니다.
세션 삭제 이해
부모가 게임 또는 제품에 대한 액세스를 취소하면:
- 세션이 삭제됨 - 최종 단계로 세션이 제거됩니다. 쿼리는 HTTP 400을 반환하여 세션이 존재하지 않았던 것처럼 보입니다
- 모든 미완료 Challenge가 실패함 - 해당 플레이어의 모든 보류 중인 Challenge가 자동으로
FAIL로 설정됩니다 - 웹훅 이벤트가 전송됨 - 삭제에 대한 웹훅 알림을 받습니다
k-ID API는 유효한 세션 상태로 ACTIVE 또는 HOLD만 반환합니다. 부모가 액세스를 취소하면 세션이 삭제되고 API는 400(찾을 수 없음)을 반환합니다. 이것은 의도적인 것입니다: 세션이 삭제되면 더 이상 존재하지 않는 것으로 처리해야 합니다. 삭제된 세션은 플레이어가 더 이상 게임에 액세스할 수 없기 때문에 실질적으로 "찾을 수 없음"입니다.
삭제된 세션 감지
웹훅을 통해(서버 측):
case "Session.Delete":
await deleteStoredSession(data.id);
await markSessionAsDeleted(data.id);
break;
세션을 가져올 때 API를 통해(서버 측):
const response = await fetch(
`https://game-api.k-id.com/api/v1/session/get?sessionId=${sessionId}`,
{ headers: { "Authorization": `Bearer ${process.env.KID_API_KEY}` } }
);
if (response.status === 400) {
const error = await response.json();
if (error.error === "NOT_FOUND") {
await deleteStoredSession(sessionId);
return res.json({ sessionDeleted: true });
}
}
세션을 쿼리할 때 NOT_FOUND 오류가 포함된 400 응답은 다음을 의미할 수 있습니다:
- 세션이 생성되지 않았음
- 세션이 삭제되었음
- 세션 ID가 유효하지 않음
애플리케이션은 이러한 모든 경우를 동일한 방식으로 처리해야 합니다: 근본적인 이유에 관계없이 플레이어가 액세스 권한이 없음을 나타내는 것으로 처리합니다. 폴링에만 의존하는 대신 웹훅을 사용하여 세션 삭제에 대한 실시간 알림을 받습니다.
연령 게이트로 리디렉션
게임 클라이언트가 서버에서 sessionDeleted: true 응답을 받으면 연령 게이트 흐름을 다시 시작합니다:
// Client-side handling
async function checkSession(sessionId) {
const response = await fetch(`/api/session/${sessionId}`);
const data = await response.json();
if (data.sessionDeleted || data.needsConsent) {
// Show explanation to the player
showDialog({
title: "Session Ended",
message: "Your session has ended. Please complete age verification to continue playing.",
buttons: [{
text: "Continue",
action: () => navigateToAgeGate()
}]
});
}
}
6단계: 새 권한에 대한 업그레이드 경로 제공
플레이어는 부모 동의가 필요한 기능에 대한 액세스를 요청할 수 있습니다. /session/upgrade API는 이 흐름을 가능하게 합니다.
업그레이드 가능 여부 확인
"부모에게 요청" 버튼을 표시하기 전에 권한을 업그레이드할 수 있는지 확인합니다. 이 로직은 서버에서 반환된 세션 데이터를 사용하여 클라이언트 측에서 실행할 수 있습니다:
// Client-side check using session data from your server
function canRequestPermission(session, permissionName) {
const permission = session.permissions.find(p => p.name === permissionName);
if (!permission) return false;
// Can only request if currently disabled and managed by GUARDIAN
return !permission.enabled && permission.managedBy === "GUARDIAN";
}
권한 업그레이드 요청
플레이어가 "부모에게 요청"을 탭하면 게임 클라이언트가 서버를 호출하고 서버가 k-ID 세션 업그레이드 API를 호출합니다:
// Server-side endpoint
app.post("/api/request-permission", async (req, res) => {
const { sessionId, permissionName } = req.body;
const response = await fetch(
"https://game-api.k-id.com/api/v1/session/upgrade",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KID_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
sessionId: sessionId,
requestedPermissions: [{ name: permissionName }]
})
}
);
const result = await response.json();
if (result.status === "PASS") {
// Permission was enabled immediately (player can manage it)
// Update stored session
await storeSession(sessionId, result.session);
return res.json({ success: true, session: result.session });
} else if (result.status === "CHALLENGE") {
// Parent consent required
return res.json({
success: false,
requiresConsent: true,
challenge: result.challenge
});
}
});
옵션 A: 세션 업그레이드 위젯 사용 (권장)
세션 업그레이드 위젯은 부모가 권한 요청을 검토하고 승인할 수 있는 완전한 사전 구축 인터페이스를 제공합니다. 웹 기반 게임을 구축하거나 iframe을 표시할 수 있는 경우 이것이 가장 간단한 접근 방식입니다.
세션 업그레이드 위젯은 보호자 관리 세션에서만 작동합니다. 플레이어의 세션이 플레이어 관리(managedBy가 "PLAYER")인 경우 /session/upgrade API를 통해 Challenge를 생성하지 않고 권한을 직접 활성화할 수 있으므로 위젯이 필요하지 않습니다.
Challenge가 반환되면 위젯 URL을 생성하여 부모에게 표시합니다:
// Server-side endpoint to generate the widget URL
app.post("/api/permission-widget", async (req, res) => {
const { challengeId, parentEmail } = req.body;
const response = await fetch(
"https://game-api.k-id.com/api/v1/widget/generate-session-upgrade-url",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KID_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
challengeId: challengeId,
email: parentEmail
})
}
);
const { url } = await response.json();
res.json({ widgetUrl: url });
});
클라이언트 측에서 iframe에 위젯을 표시합니다:
<iframe
id="permission-widget"
src="WIDGET_URL"
width="100%"
height="600"
allow="camera;payment;publickey-credentials-get;publickey-credentials-create"
frameborder="0">
</iframe>
위젯은 부모 확인 및 권한 승인을 포함한 전체 동의 흐름을 처리합니다. 흐름이 완료되면 Widget.ExitReview DOM 이벤트를 수신한 다음 서버에서 세션을 새로 고칩니다.
옵션 B: 커스텀 동의 흐름 구축
UI를 완전히 제어해야 하거나 iframe을 사용할 수 없는 경우 커스텀 동의 흐름을 구축합니다. 부모가 동의를 제공할 수 있는 옵션을 제공합니다:
// Client-side UI
function showConsentRequest(challenge) {
showDialog({
title: "Ask a Parent",
message: "A parent needs to approve this feature. How would you like to reach them?",
options: [
{
label: "Send an email",
action: () => showEmailInput(challenge.challengeId)
},
{
label: "Show QR code",
action: () => showQRCode(challenge.url)
},
{
label: "Show code",
sublabel: `Go to asktoplay.com and enter: ${challenge.oneTimePassword}`,
action: () => showCodeDisplay(challenge.oneTimePassword)
}
]
});
}
커스텀 동의 흐름 처리에 대한 자세한 내용은 커스텀 연령 게이트 빠른 시작을 참조하세요.
모범 사례
성능 권장 사항
- 가능한 경우 웹훅 선호: 폴링보다 효율적이고 실시간 업데이트를 제공하기 때문
etag매개변수 사용:/session/get을 호출할 때 불필요한 데이터 전송을 방지하기 위해- 세션을 로컬에 캐시: 필요할 때만 업데이트를 가져옴
- 자주 폴링하지 않음: 폴링해야 하는 경우 게임플레이 중 최소 30초 간격으로 요청을 대기하거나 게임 시작 시에만 확인
엣지 케이스 처리
- 오프라인 플레이어: 세션을 캐시하고 캐시된 권한을 적용합니다. 연결이 복원되면 업데이트를 확인합니다.
- 여러 디바이스: 플레이어가 여러 디바이스를 사용할 수 있는 경우 일관성을 보장하기 위해 계정과 연결된 클라우드 스토리지에 세션을 저장합니다.
- 게임플레이 중 연령 증가: 긴 게임플레이 세션의 경우 생일로 트리거된 변경 사항을 포착하기 위해 주기적인 세션 새로 고침을 고려합니다.
다음 단계
세션 및 권한 관리를 구현했으므로 다음 리소스를 탐색하세요:
- Sessions: 세션 수명 주기 및 구조 심층 분석
- Challenges: 동의 Challenge, 상태 처리 및 모범 사례에 대한 완전한 가이드
- Permissions: 권한 유형 및 관리에 대한 자세한 정보
- Permissions: 업그레이드 흐름에 대한 자세한 내용
- Webhooks: 웹훅 구현 및 검증에 대한 완전한 가이드
Session.ChangePermissions: 웹훅 이벤트 참조- Best practices: 추가 구현 가이드