Login and User Info Retrieval Flow
This page describes the complete path from login to retrieving sensitive information, together with orchestration code you can copy into your game script. For the parameters and return values of each API, see the API overview.
Roles
| Role | Responsibility |
|---|---|
| Game | Game client script; calls the sud.* APIs |
| SUD OP | OpenPaaS runtime; performs user authentication and encrypts and signs sensitive information |
| Game SVR | Game server; consumes code to obtain session data, issues its own session, and verifies and decrypts sensitive data |
| SUD OP SVR | OpenPaaS server; manages user identity and session keys |
Complete Flow
Key Constraints
codecan be used only once and is consumed by Game SVR. The client must not reuse it or keep it for long.auth.code2sessionmust be called from the server. The request carriesgame_idandsecret, which must never appear on the client.session_keyis stored only on Game SVR. Do not deliver it to the client, place it in configuration readable by the front end, or write it to logs. Signature verification and decryption in Phase 3 must use thesession_keyobtained in the same Phase 1 login.- Sensitive data is encrypted end to end. The client only relays it; any decryption attempt on the client will fail.
rawDatamust be passed unchanged. Game SVR must not parse and re-serialize it when verifying the signature.- Keep basic and sensitive information separate. When you only need the nickname and avatar, use sud.getUserInfo: the path is shorter and requires no server-side encryption or decryption.
Orchestration Code
All three APIs are callback-based. Wrap them in Promises first, then orchestrate them in order. requestGameServerLogin and requestGameServerDecrypt are your own game server endpoints; replace them with your backend implementation. They are not provided by OpenPaaS.
javascript
function login() {
return new Promise((resolve, reject) => {
sud.login({
success: (res) => resolve(res.code),
fail: (err) => reject(err),
complete: () => {},
});
});
}
function getUserInfo() {
return new Promise((resolve, reject) => {
sud.getUserInfo({
success: (res) => resolve(res),
fail: (err) => reject(err),
complete: () => {},
});
});
}
function getUserProfile() {
return new Promise((resolve, reject) => {
sud.getUserProfile({
success: (res) => resolve(res),
fail: (err) => reject(err),
complete: () => {},
});
});
}
async function startLoginFlow() {
// Phase 1: obtain the single-use code and let Game SVR exchange it for a session
const code = await login();
const session = await requestGameServerLogin(code);
// session = { token, openid }; token is issued by Game SVR itself
// Phase 2: basic information, usable directly in the UI
const userInfo = await getUserInfo();
// Phase 3: sensitive information; the client only relays it and Game SVR verifies and decrypts
const profile = await getUserProfile();
const sensitive = await requestGameServerDecrypt(session.token, {
rawData: profile.rawData,
encryptedData: profile.encryptedData,
iv: profile.iv,
signature: profile.signature,
userInfo,
});
return { session, userInfo, sensitive };
}Every step can fail. Handle errors step by step and stop instead of continuing after a failure; do not catch everything at the end and treat it as a successful login.
