Last active
October 9, 2021 22:07
-
-
Save ThisNils/23c5dc9a49164e5419219a1654c0827c to your computer and use it in GitHub Desktop.
Example on how to create and use device auths.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const request = require('request-promise'); | |
const fs = require('fs').promises; | |
const BASE_URL = 'https://www.epicgames.com/id/api'; | |
const BASE_PROD = 'https://account-public-service-prod03.ol.epicgames.com/account/api/oauth'; | |
const DEVICE_AUTH = 'https://account-public-service-prod.ol.epicgames.com/account/api/public/account'; | |
const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'; | |
const IOS_TOKEN = 'MzQ0NmNkNzI2OTRjNGE0NDg1ZDgxYjc3YWRiYjIxNDE6OTIwOWQ0YTVlMjVhNDU3ZmI5YjA3NDg5ZDMxM2I0MWE='; | |
const LAUNCHER_TOKEN = 'MzRhMDJjZjhmNDQxNGUyOWIxNTkyMTg3NmRhMzZmOWE6ZGFhZmJjY2M3Mzc3NDUwMzlkZmZlNTNkOTRmYzc2Y2Y='; | |
/* | |
* This is an example on how to login using device auth. | |
* For the first start, please enter email&password OR exchangeCode. | |
* | |
* You will need an exchangeCode if you get the captcha error. | |
* You can get one at https://www.epicgames.com/id/login?redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fid%2Fapi%2Fexchange (make sure you're logged out first). | |
* ExchangeCodes expire after 300 seconds and can only be used once. | |
* | |
* IMPORTANT: Do not share the device auth details with anyone. | |
* However if you unintentionally shared them, just reset your password. | |
* | |
* UPDATE: You can now get launcher tokens using device auth. | |
*/ | |
const email = ''; | |
const password = ''; | |
const exchangeCode = ''; | |
const deviceAuthPath = './deviceAuthDetails.json'; | |
const getLauncherToken = false; | |
const generateDeviceAuth = async (code) => { | |
if (!code) { | |
const jar = request.jar(); | |
await request({ | |
url: `${BASE_URL}/reputation`, | |
jar, | |
headers: { | |
'User-Agent': USER_AGENT, | |
}, | |
json: true, | |
}); | |
await request({ | |
url: `${BASE_URL}/csrf`, | |
jar, | |
headers: { | |
'User-Agent': USER_AGENT, | |
}, | |
}); | |
const { cookies } = JSON.parse(JSON.stringify(jar))._jar; | |
try { | |
await request.post({ | |
url: `${BASE_URL}/login`, | |
headers: { | |
'x-xsrf-token': cookies.find((c) => c.key === 'XSRF-TOKEN').value, | |
'Content-Type': 'application/json', | |
'User-Agent': USER_AGENT, | |
}, | |
jar, | |
form: { | |
email, | |
password, | |
rememberMe: true, | |
}, | |
}); | |
} catch (err) { | |
await request.post({ | |
url: `${BASE_URL}/login`, | |
headers: { | |
'x-xsrf-token': cookies.find((i) => i.key === 'XSRF-TOKEN').value, | |
'Content-Type': 'application/json', | |
'User-Agent': USER_AGENT, | |
}, | |
jar, | |
form: { | |
email, | |
password, | |
rememberMe: true, | |
}, | |
}); | |
} | |
code = (await request({ | |
url: `${BASE_URL}/exchange`, | |
headers: { | |
'x-xsrf-token': cookies.find((i) => i.key === 'XSRF-TOKEN').value, | |
'User-Agent': USER_AGENT, | |
}, | |
jar, | |
json: true, | |
})).code; | |
} | |
const iosToken = await request.post({ | |
url: `${BASE_PROD}/token`, | |
headers: { | |
'Content-Type': 'application/x-www-form-urlencoded', | |
Authorization: `basic ${IOS_TOKEN}`, | |
'User-Agent': USER_AGENT, | |
}, | |
form: { | |
grant_type: 'exchange_code', | |
exchange_code: code, | |
includePerms: false, | |
}, | |
json: true, | |
}); | |
const deviceAuthDetails = await request.post({ | |
url: `${DEVICE_AUTH}/${iosToken.account_id}/deviceAuth`, | |
headers: { | |
Authorization: `bearer ${iosToken.access_token}`, | |
}, | |
json: true, | |
}); | |
return { | |
accountId: deviceAuthDetails.accountId, | |
deviceId: deviceAuthDetails.deviceId, | |
secret: deviceAuthDetails.secret, | |
}; | |
}; | |
(async () => { | |
let deviceAuthDetails; | |
let deviceAuthFileBuffer = ''; | |
try { | |
deviceAuthFileBuffer = await fs.readFile(deviceAuthPath); | |
} catch (err) { | |
await fs.writeFile(deviceAuthPath, ''); | |
} | |
if (deviceAuthFileBuffer.length !== 0) { | |
deviceAuthDetails = JSON.parse(deviceAuthFileBuffer); | |
} else { | |
deviceAuthDetails = await generateDeviceAuth(exchangeCode); | |
await fs.writeFile(deviceAuthPath, JSON.stringify(deviceAuthDetails)); | |
} | |
const fortniteToken = await request.post({ | |
url: `${BASE_PROD}/token`, | |
form: { | |
grant_type: 'device_auth', | |
account_id: deviceAuthDetails.accountId, | |
device_id: deviceAuthDetails.deviceId, | |
secret: deviceAuthDetails.secret, | |
}, | |
headers: { | |
'Content-Type': 'application/x-www-form-urlencoded', | |
Authorization: `basic ${IOS_TOKEN}`, | |
}, | |
json: true, | |
}); | |
if (getLauncherToken) { | |
const launcherExchange = await request.get({ | |
url: 'https://account-public-service-prod.ol.epicgames.com/account/api/oauth/exchange', | |
headers: { | |
Authorization: `${fortniteToken.token_type} ${fortniteToken.access_token}`, | |
}, | |
json: true, | |
}); | |
const launcherToken = await request.post({ | |
url: `${BASE_PROD}/token`, | |
headers: { | |
'Content-Type': 'application/x-www-form-urlencoded', | |
Authorization: `basic ${LAUNCHER_TOKEN}`, | |
'User-Agent': USER_AGENT, | |
}, | |
form: { | |
grant_type: 'exchange_code', | |
exchange_code: launcherExchange.code, | |
includePerms: false, | |
}, | |
json: true, | |
}); | |
console.log(`Your Launcher token is ${launcherToken.access_token}`); | |
} | |
console.log(`Your Fortnite token is ${fortniteToken.access_token}`); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
UPDATE: You can now fetch the launcher token aswell!