Skip to content

Instantly share code, notes, and snippets.

@JohnTube
Last active February 8, 2021 10:15
Show Gist options
  • Save JohnTube/122568b1183db131d50f5f17935ee21a to your computer and use it in GitHub Desktop.
Save JohnTube/122568b1183db131d50f5f17935ee21a to your computer and use it in GitHub Desktop.
Photon custom authentication done in PlayFab in a special way to make use of Data and AuthCookie features but also allow/block list AppVersions.
// custom auth endpoint: https://{PlayFabTitleId}.playfablogic.com/webhook/1/prod/{PhotonSecretKey}/CustomAuth
// you can replace CustomAuth handler name and also in the URL
// C# client snippet:
// AuthenticationValues authValues = new AuthenticationValues();
// authValues.AuthType = CustomAuthenticationType.Custom;
// Dictionary<string, object> data = new Dictionary<string, object>(6);
// data["UserId"] = userId; // PlayFabId
// data["AppId"] = appId; // Photon AppId
// data["AppVersion"] = appVersion // Photon AppVersion
// data["Ticket"] = ticket; // PlayFab auth session ticket
// data["Token"] = token; // Photon auth token obtained from PlayFab via client API call GetPhotonAuthenticationToken
// data["Nickname"] = nickanem; // optional
// authValues.SetAuthPostData(data);
handlers.CustomAuth = function (args, context)
{
try {
var debug = true; // set to true to debug
if (debug === true) {
server.WriteTitleEvent(
{
EventName: "photon_custom_auth",
Timestamp: new Date(),
Body: { args: args, context: context, currentPlayerId: currentPlayerId }
}
);
}
// PlayFab already checks AppId and UserId
var appId = args.AppId;
var userId = args.UserId;
var appVersion = args.AppVersion;
if (appVersion === undefined) {
return { ResultCode: 2, Message: 'AppVersion is undefined' };
}
var token = args.Token;
if (token === undefined) {
return { ResultCode: 3, Message: 'Token is undefined' };
}
var ticket = args.Ticket;
if (ticket === undefined) {
return { ResultCode: 4, Message: 'Ticket is undefined' };
}
var nickname = args.Nickname;
var titleId = script.titleId;
//http.request(url, method, content, contentType, headers, logRequestAndResponse);
//script.revision;
//script.titleId;
//var result = server.AuthenticateUserTicket(request);
//log.info(msg, data);
//log.debug(msg, data);
//log.error(msg, data);
var request = { SessionTicket: ticket };
var result = server.AuthenticateSessionTicket(request);
//var result = server.GetUserAccountInfo(request);
if (debug === true) {
server.WriteTitleEvent(
{
EventName: "AuthenticateSessionTicket",
Timestamp: new Date(),
Body: { req: request, res: result }
}
);
}
var userInfo = result.UserInfo;
if (userInfo !== undefined) {
if (userId !== userInfo.PlayFabId)
{
return { ResultCode: 5, Message: 'UserId and SessionTicket mismatch' };
}
if (userInfo.TitleInfo !== undefined) {
var userTitleInfo = userInfo.TitleInfo;
if (userTitleInfo.isBanned === true) {
return { ResultCode: 6, Message: 'User is banned' };
}
if (nickname === undefined) {
nickname = userTitleInfo.DisplayName;
}
}
if (nickname === undefined) {
nickname = userInfo.Username;
}
}
var url = "https://" + titleId + ".playfabapi.com/photon/authenticate?username=" + userId + "&token=" + token;
var httpMethod = "get";
var response = http.request(url, httpMethod);
var authRes = JSON.parse(response);
if (debug === true) {
server.WriteTitleEvent(
{
EventName: "PhotonAuthenticate",
Timestamp: new Date(),
Body: { url: url, httpMethod: httpMethod, response: response }
}
);
}
if (authRes.ResultCode === undefined) {
authRes.ResultCode = authRes.resultCode;
}
if (authRes.ResultCode !== 1) {
if (authRes.ResultCode === undefined)
{
authRes.ResultCode = 252;
}
return authRes;
}
if (nickname === undefined || nickname === null)
{
if (authRes.Nickname === undefined) {
if (authRes.nickname !== undefined && authRes.nickname !== null)
{
nickname = authRes.nickname;
}
}
else if (authRes.Nickname !== null) {
nickname = authRes.Nickname;
}
}
var keys = ["photon_appversion_allowlist", "photon_appversion_blocklist"];
var titleData = server.GetTitleData({
Keys: keys
});
if (debug === true)
{
server.WriteTitleEvent(
{
EventName: "GetTitleData",
Timestamp: new Date(),
Body: { Keys: keys, titleData: titleData }
}
);
}
var list = titleData.Data["photon_appversion_allowlist"]
if (list !== undefined) {
var array = list.split(',');
if (array.indexOf(appVersion) === -1) {
return { ResultCode: 7, Message: 'AppVersion not allowed' };
}
} else {
list = titleData.Data["photon_appversion_blocklist"]
if (list !== undefined) {
var array = list.split(',');
if (array.indexOf(appVersion) !== -1) {
return { ResultCode: 8, Message: 'AppVersion not allowed' };
}
}
}
// todo: transform userInfo into a flat one level JSON object (Dictionary) and return in Data.
var secret = { s: "secret" };
// todo: inject JSON object (flat one level) AuthCookie
var data = { k: "value" };
return { ResultCode: 1, UserId: userId, Nickname: nickname, Data: data, AuthCookie: secret };
} catch (e) {
if (e.cloudScriptErrorCode !== undefined) {
return { ResultCode: 254, Message: e.cloudScriptErrorCode + ': ' + e.stack };
}
if (e.name !== undefined && e.message !== undefined)
{
return { ResultCode: 255, Message: e.name + ': ' + e.message };
}
return { ResultCode: 253, Message: 'error:' + e };
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment