Authentifizierung über Deep-Links einrichten
Deep Links ermöglichen es dem Nutzer, sich mit einem Klick über das Spiel im Web Shop zu authentifizieren, anstatt den Authentifizierungsprozess mittels Benutzer-ID oder Xsolla Login zu durchlaufen.
Ist das Spiel auf dem Mobilgerät des Nutzers installiert, wird dieser über einen Deep Link zum Spiel weitergeleitet und ein Autorisierungstoken abgerufen.
Ablauf für den Nutzer
In der mobilen App
- Ein nicht autorisierter Nutzer klickt im Web Shop auf die Anmelden- oder Kaufen-Schaltfläche. Daraufhin öffnet sich ein Modalfenster zur Eingabe der Benutzer-ID oder zur Anmeldung beim Handyspiel.
- Der Nutzer klickt auf die Anmelden-Schaltfläche.
- Der Nutzer wird erst zum Spiel und dann automatisch als autorisierter Nutzer zum Web Shop weitergeleitet.
In der Desktop-Version
- Ein nicht autorisierter Nutzer klickt im Web Shop auf die Anmelden- oder Kaufen-Schaltfläche. Daraufhin öffnet sich ein Modalfenster zur Eingabe der Benutzer-ID oder zur Anmeldung bei der mobilen Version des Spiels per QR-Code.
- Der Nutzer scannt den QR-Code mit seinem Mobilgerät, daraufhin öffnet sich der Web Shop auf seinem Mobilgerät.
- Die mobile Version des Spiels öffnet sich auf dem Mobilgerät des Nutzers.
- Der Nutzer wird automatisch auf dem Mobilgerät als autorisierter Nutzer zum Web Shop weitergeleitet.
Interaktionsablauf
Einrichtung
Aufseiten des Spiels
- Registrieren Sie in den Einstellungen Ihrer Spiele-App ein URL-Schema, um das Spiel über einen Deep Link zu öffnen:
- in Android-Anwendungen – in der Datei
AndroidManifest.xml
- in iOS-Anwendungen – in der Datei
Info.plist
- in Android-Anwendungen – in der Datei
gamename://authorize
, wobei:gamename
der Name Ihres Spiels ist, das sich zum Zweck der Benutzerauthentifizierung auf einem Mobilgerät öffnen soll,authorize
der Name einer beispielhaften Aktion ist, die nach dem Öffnen des Spiels “gamename” ausgeführt werden soll. Der Aktionsname muss mit dem Namen der entsprechenden Aktionen im Betriebssystem Ihrer Anwendung übereinstimmen.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>gamename</string>
</array>
</dict>
</array>
Registrierung eines URL-Schemas in Android-Anwendungen (Beispiel):
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="gamename" android:host="authorize" />
</intent-filter>
- Implementieren Sie, dass ein Autorisierungstoken im JWT-Format mithilfe der spielpezifischen Benutzer-ID generiert wird.
Parameter | Typ | Beschreibung |
---|---|---|
loginId | string | ID der Autorisierungsmethode aus dem Kundenportal. Erforderlich. |
webhookUrl | string | RL für den Empfang des Webhooks Benutzervalidierung im Web Shop. Die URL sollte mit der Adresse übereinstimmen, die bei der Einrichtung der Authentifizierung über Benutzer-ID angegeben wurde. Xsolla erwartet als Antwort auf den Webhook den HTTP-Statuscode 200 , um den Web-Shop-Nutzer zu autorisieren. Erhält Xsolla eine Antwort mit dem HTTP-Statuscode 404 erhält oder gar keine Antwort, wird der Nutzer nicht autorisiert.Sie können den Wert "webhookUrl": "https://nowebhook.com" angeben, wenn Sie Webhooks bei der Authentifizierung über Deep Links deaktivieren möchten. In diesem Fall prüft Xsolla nicht, ob der Nutzer existiert. Stellen Sie also sicher, dass Sie im Parameter user.id eine im Spiel existierende Benutzer-ID übermitteln.Erforderlich.URL für den Empfang des Webhooks Benutzervalidierung im Web Shop. Die URL sollte mit der Adresse übereinstimmen, die bei der Einrichtung der Authentifizierung über Benutzer-ID angegeben wurde. Xsolla erwartet als Antwort auf den Webhook den HTTP-Statuscode 200 , um den Web-Shop-Nutzer zu autorisieren. Erhält Xsolla eine Antwort mit dem HTTP-Statuscode 404 erhält oder gar keine Antwort, wird der Nutzer nicht autorisiert.Sie können den Wert “webhookUrl”: “https://nowebhook.com” angeben, wenn Sie Webhooks bei der Authentifizierung über Deep Links deaktivieren möchten. In diesem Fall prüft Xsolla nicht, ob der Nutzer existiert. Stellen Sie also sicher, dass Sie im Parameter user.id eine im Spiel existierende Benutzer-ID übermitteln.Erforderlich. |
settings.projectId | string | Projekt-ID. Diese wird im Kundenportal neben dem Namen des Projekts in der Adresszeile des Browsers angezeigt. Die URL weist das folgende Format auf: https://publisher.xsolla.com/merchant ID/Publisher Account section . Erforderlich. |
user.id | string | Benutzer-ID im Spiel. Erforderlich. |
user.name | string | Benutzername. Erforderlich. |
Aufruf der API-Methode mittels curl für die Generierung des Benutzertokens (Beispiel):
- curl
curl --location 'https://sb-user-id-service.xsolla.com/api/v1/user-id' \
--header 'Content-Type: application/json' \
--data '{
"loginId": "000001aa-001a-0ab0-00001-01a01a01a01a",
"webhookUrl": "https://nowebhook.com",
"settings": {
"projectId": 123456,
"merchantId": 123456
},
"user": {
"id": "123",
"name": "a-user-name"
}
}'
Die Antwort sieht in etwa wie folgt aus: {token=“JWT_TOKEN”}
.
- Fügen Sie ein Pop-up-Fenster mit einer Benachrichtigung über die erfolgreiche Autorisierung hinzu (optional).
- Implementieren Sie, dass der Web Shop im Browser unter Verwendung des abgerufenen Benutzertokens geöffnet wird.
Erstellen einer URL für das Öffnen des Web Shops im Browser für einen autorisierten Nutzer (Beispiel):
https://example.com/?token={token}
, wenn Sie eine eigene Domain verwenden,https://example.xsollasitebuilder.com/?token={token}
, wenn Sie eine Xsolla-Domain verwenden,
{token}
der Autorisierungstoken des Nutzers ist.Innerhalb von Site Builder
Sie können die Einstellungen auf der Website im Site Builder selbst vornehmen, indem Sie die unten aufgeführten Codebeispiele verwenden.Wenn Sie Hilfe bei der Einrichtung benötigen, wenden Sie sich an Ihren Customer Success Manager oder senden Sie eine E-Mail an csm@xsolla.com.
- Öffnen Sie das Projekt im Kundenportal.
- Klicken Sie in der Seitenleiste auf Site Builder.
- Klicken Sie bei der gewünschten Web-Shop-Seite, für die eine Authentifizierung über Benutzer-ID eingerichtet ist, auf Konfigurieren.
- Ergänzen Sie die Möglichkeit einer Deep-Link-Authentifizierung im Block Benutzerdefinierter Code.
- Fügen Sie im Block Benutzerdefinierter Code auf der Registerkarte JavaScript den folgenden benutzerdefinierten Code ein. Dieser Code implementiert die Deep-Link-Authentifizierung für die mobile und die Desktop-Version.
- Ersetzen Sie die Werte der Konstanten im Code durch Ihre Werte, wobei:
DEEPLINK_URL
das URL-Schema ist, das zum Öffnen des Spiels über den Deep Link verwendet wird,QR_CODE
der QR-Code (im SVG-Format) zum Öffnen des Spiels ist. Der QR-Code sollte einen Link zum Web Shop mit dem Parametersource = pc
enthalten,deeplink__description
die Beschreibung ist, die unter der Autorisierungsschaltfläche in der App angezeigt wird.qr-code-auth__description
die Beschreibung ist, die unter dem QR-Code in der Desktop-Version des Spiels angezeigt wird.
- js
{
const DEEPLINK_URL = 'gamename://authorize';
const QR_CODE = `YOUR_SVG_WITH_QR_CODE`;
handleQRCodeRedirect();
// Event handlers are set up for opening the authentication modal or for successful authentication.
// If the event of opening the authentication modal occurs, the handler is triggered and a button or QR code is added to this window.
// If the event of successful authentication occurs, the handler is triggered and the successful authentication modal is opened.
window.addEventListener('custom-event:modal:render', updateLoginModal);
window.addEventListener('custom-event:authorization:login', showLoginSuccessPopup);
let getToken;
const searchParams = new URLSearchParams(window.location.search);
const tokenParam = searchParams.get('token');
if (tokenParam) {
showLoginSuccessPopup(tokenParam);
}
window.SB.subscribe(api => {
getToken = api.getToken;
});
// Customization of the authentication modal window (adding a QR code for the desktop version of the game or a login button for the mobile version of the game).
function updateLoginModal({detail}) {
const {name, element} = detail;
if (name !== 'user-id' || element.dataset.isQrAdded === 'true') return;
const isMobile = checkMobileDevice();
const ModalBody = element.querySelector('.ui-site-modal-window__body');
const ModulInput = ModalBody.querySelector('.user-id-modal__input');
element.classList.toggle('mobile-layout', isMobile);
ModalBody.append(getTemplate(isMobile));
element.dataset.isQrAdded = true;
}
// Function to display the successful authentication modal window.
function showLoginSuccessPopup(t) {
let username = 'Gamer';
try {
const token = getToken?.() || t;
if (token) {
const jwtData = parseJwt(token);
const payload = JSON.parse(jwtData.payload);
if (payload.userInfo.name) {
username = payload.userInfo.name;
} else if (jwtData.username) {
username = jwtData.username;
} else if (jwtData.server_custom_id) {
username = jwtData.server_custom_id;
}
}
} catch (e) {
console.log('error', e);
}
const Modal = document.querySelector('.deeplink-auth');
const ModalTitle = Modal.querySelector('.deeplink-auth__title');
ModalTitle.textContent = ModalTitle.textContent.replace(/\{username}/g, username);
Modal.classList.add('_visible');
Modal.querySelector('.deeplink-auth__button').addEventListener('click', closeModal);
function closeModal() {
Modal.classList.remove('_visible');
}
}
// Function that displays a QR code for the desktop version of the game or a login button for the mobile version of the game. Your_game should be replaced with the actual name of your game. To continue with the authentication, the game has to be installed on the user's phone.
function getTemplate(isMobile) {
const Deeplink = document.createElement('div');
if (isMobile) {
Deeplink.innerHTML = `
<div class="deeplink__title"><span class="deeplink__title-text">or login via game</span></div>
<a href="${DEEPLINK_URL}" class="deeplink__button" rel="noopener">Login via Mobile Game</a>
<div class="deeplink__description">
You need to have the Your_game installed on your phone in order to proceed with authorization and purchase
</div>
`;
return Deeplink;
}
Deeplink.innerHTML = `
<div class="separator">
<span class="separator__text">or login via game</span>
</div>
<div class="qr-code-auth">
<div class="qr-code-auth__image">${QR_CODE}</div>
<span class="qr-code-auth__description">
Scan the QR code with your phone and you will continue purchasing on your mobile device
</span>
</div>
`;
return Deeplink;
}
function checkMobileDevice() {
return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
}
// Function that decodes the JWT token and returns its payload as a JavaScript object.
function parseJwt(token) {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
}
// Function to verify the vent occurred when the user scanned the QR code.
function handleQRCodeRedirect() {
const url = new URL(window.location.href);
const source = url.searchParams.get('source');
if (source === 'pc') {
if (checkMobileDevice()) {
const button = document.getElementById("deeplink-redirect");
button.click();
}
setTimeout(function () {
url.searchParams.delete('source');
window.history.pushState({}, '', url);
}, 2000);
}
}
}
- Fügen Sie im Block Benutzerdefinierter Code auf der Registerkarte HTML den Code für ein Modalfenster ein, das die erfolgreiche Autorisierung im Web Shop signalisiert. Sie können Ihre eigenen Text festlegen.
- html
<div class="ui-site-modal-window deeplink-auth">
<div class="deeplink-auth__body">
<div class="deeplink-auth__image"></div>
<div class="deeplink-auth__title">Hi, {username}!</div>
<div class="deeplink-auth__description">You’ve successfully logged in to the Web Shop</div>
<button class="deeplink-auth__button">Continue</button>
</div>
</div>
<a href="gamename://authorize" id="deeplink-redirect" style="display: none;"></a>
- Fügen Sie im Block Benutzerdefinierter Code auf der Registerkarte CSS Stile für neue Bedienoberflächenkomponenten hinzu. Empfohlene Stile sind unten vorgeschlagen. Geben Sie die URL Ihres eigenen Bildes an, das bei erfolgreicher Autorisierung angezeigt wird.
- css
--deeplink-success-image-url: url("Successful_authorization_image_url");
.html-v2:has(.deeplink-auth._visible) {
z-index: var(--modalsZIndex);
}
.user-id-modal__content {
padding: 0 16px !important;
}
@media (min-width: 768px) {
.user-id-modal__content {
max-width: 460px !important;
padding: 0 3.8rem 4rem !important;
overflow: auto;
justify-content: center;
}
}
.mobile-layout .user-id-modal__close {
right: 8px;
top: 16px;
}
.user-id-modal__logo {
width: 109px;
height: 38px;
margin: 4rem auto 2rem;
}
.user-id-modal.mobile-layout .user-id-modal__logo {
margin: 3rem auto 2.5rem;
}
.user-id-modal__wrapper {
margin-top: 0;
}
.user-id-modal__title {
margin-bottom: 3rem;
}
.user-id-modal__input-wrapper .ui-site-input {
height: 41px;
}
.user-id-modal__input {
margin-top: 0;
border-radius: var(--border-radius-16);
}
.user-id-modal__button {
height: auto;
margin: 12px auto 0;
padding: 1.25rem;
border-radius: var(--border-radius-16);
}
.user-id-modal__button .simple-button__text {
font-size: 1.8rem;
font-weight: 500;
line-height: 2.5rem;
letter-spacing: 0.5px;
}
.user-id-modal .ui-site-instruction-cut__title .ui-site-description {
margin-bottom: 3rem;
font-size: 1.2em;
}
.user-id-modal .ui-site-instruction-cut__steps {
overflow-y: visible;
}
.user-id-modal .ui-site-instruction-card:first-child {
margin-top: 0;
}
.user-id-modal .ui-site-instruction-card:last-child {
padding-bottom: 4rem;
}
.user-id-modal .separator {
display: flex;
margin-bottom: 3.8rem;
align-items: center;
}
.user-id-modal .separator__text {
padding: 0 1.5rem;
font-family: var(--main-font);
font-size: 1.8rem;
font-weight: 500;
line-height: 2.5rem;
letter-spacing: 0.8px;
}
.user-id-modal .separator::before,
.user-id-modal .separator::after {
content: "";
background-color: #797979;
height: 1px;
flex-grow: 1;
}
.user-id-modal .qr-code-auth__image {
display: block;
width: 160px;
height: 160px;
margin: 0 auto 20px;
}
.user-id-modal .qr-code-auth__image svg {
display: block;
width: 100%;
height: 100%;
}
.user-id-modal .qr-code-auth__description {
display: inline-block;
font-family: var(--main-font);
font-size: 1.5rem;
font-weight: 400;
line-height: 2.5rem;
text-align: center;
color: rgba(255, 255, 255, 0.7);
}
.deeplink__title {
display: flex;
margin-bottom: 3.8rem;
align-items: center;
}
.deeplink__title-text {
padding: 0 1.5rem;
font-family: var(--main-font);
font-size: 1.8rem;
font-weight: 500;
line-height: 2.5rem;
letter-spacing: 0.8px;
}
.user-id-modal .deeplink__title::before,
.user-id-modal .deeplink__title::after {
content: "";
background-color: #797979;
height: 1px;
flex-grow: 1;
}
.deeplink__button {
display: block;
margin-bottom: 2.2rem;
padding: 1.3rem;
font-family: var(--main-font);
font-size: 1.8rem;
font-weight: 500;
line-height: 2.5rem;
letter-spacing: 0.5px;
text-align: center;
color: var(--button-text-color);
background: var(--accent-color);
border-radius: var(--border-radius-16);
text-decoration: none;
transition: transform .2s cubic-bezier(.509, .001, .25, 1);
}
.deeplink__button:hover {
transform: scale(.95);
}
.deeplink__description {
margin-bottom: 2rem;
font-family: var(--main-font);
font-size: 1.6rem;
line-height: 2.3rem;
text-align: center;
color: rgba(255, 255, 255, 0.7);
letter-spacing: 0.5px;
}
.deeplink__cta-wrapper {
display: flex;
flex-direction: row;
gap: 1.8rem;
padding: 0 1.2rem;
}
.deeplink__cta-wrapper .ui-site-calltoaction__item {
margin: 0;
flex-grow: 2;
}
.deeplink__cta-wrapper .ui-site-calltoaction {
width: 100%;
min-width: auto;
height: auto;
min-height: auto;
padding-bottom: 36%;
background-size: contain;
border-radius: 0;
}
.deeplink-auth {
display: none;
}
.deeplink-auth._visible {
display: flex;
}
.deeplink-auth__body {
position: relative;
width: 100%;
max-width: 336px;
padding: 16px;
border-radius: 12px;
background-color: var(--colors-core-background-secondary-rgb);
border: var(--border-size) solid var(--border-color);
font-family: var(--main-font);
color: var(--colors-core-text-primary);
}
@media (min-width: 768px) {
.deeplink-auth__body {
max-width: 460px;
padding: 24px 30px;
}
}
.deeplink-auth__image {
margin-bottom: 20px;
padding-bottom: 49%;
border-radius: 12px;
background-image: var(--deeplink-success-image-url);
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
@media (min-width: 768px) {
.deeplink-auth__image {
padding-bottom: 37%;
}
}
.deeplink-auth__title {
margin-bottom: 10px;
font-size: 20px;
font-weight: 500;
line-height: 24px;
text-align: center;
letter-spacing: 0.7px;
}
@media (min-width: 768px) {
.deeplink-auth__title {
margin-bottom: 20px;
font-size: 24px;
line-height: 30px;
}
}
.deeplink-auth__description {
margin-bottom: 20px;
font-size: 13px;
font-weight: 400;
line-height: 18px;
text-align: center;
letter-spacing: 0.5px;
color: rgba(255, 255, 255, 0.7);
}
.deeplink-auth__button {
display: block;
width: 100%;
padding: 1.3rem;
font-family: var(--main-font);
font-size: 1.8rem;
font-weight: 500;
line-height: 2.5rem;
letter-spacing: 0.5px;
text-align: center;
color: var(--button-text-color);
background: var(--accent-color);
border-radius: var(--border-radius-16);
text-decoration: none;
transition: transform .2s cubic-bezier(.509, .001, .25, 1);
}
@media (min-width: 768px) {
.deeplink-auth__button {
padding: 12px;
font-size: 16px;
line-height: 24px;
}
}
.deeplink-auth__button:hover {
transform: scale(.95);
}
War dieser Artikel hilfreich?
Diese Seite bewerten
Jetzt nicht
Vielen Dank für Ihr Feedback!
Haben Sie einen Tippfehler oder einen anderen Textfehler gefunden? Wählen Sie den Text aus und drücken Sie Strg+Eingabe.