Initial design
I would like the take the very first paragraph to get the logical basics down. Programming implementation down the road is “just” a question of a language syntax.
Before I wrote anything there was reconnaisance to be made. With the help of the Chrome Developer tools I recorded the steps needed to login to the overview page (automatic redirect).
Login consists of the two levels:
- Login with the e-mail which takes us to the overview of servers and already active accounts
- Login to the specific account
Firstly I needed to set the minimum goal. The goal was to successfully login to the game and just output the pure html; if successful I would get the wall of text in the console, otherwise just a short piece of redirect code (HTTP 3011).
Using apitester.com for quick and dirty test.
If successful, the post request should return the token, among other things.
Request url:
https://gameforge.com/api/v1/auth/thin/sessions
Request method:
POST
Request body:
identity=en.GB.scraper@gmail.com&password=Scraper12345&locale=de_DE&gfLang=de&platformGameId=1dfd8e7e-6e1a-4eb1-8c64-03c3b62efd2f&gameEnvironmentId=0a31d605-ffaf-43e7-aa02-d06df7116fc8&autoGameAccountCreation=false
Request valid response body:
{"token":"e9f942cc-b714-462b-91bb-ef91b40f08d1",
"isPlatformLogin":true,
"isGameAccountMigrated":false,
"platformUserId":"95ddac3a-d1b6-4160-9a5b-2a623f8d94de",
"isGameAccountCreated":false,
"hasUnmigratedGameAccounts":false}
Request invalid response body:
{"error":{"message":"Forbidden"}}
Process diagram: POST form data –> receive valid response –> receive invalid response
Let’s see how the first step looks like. Used library: request-promise 2 Success criteria: fetch all the accounts bound to the user/player
const rp = require('request-promise')
var user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36';
const tough = require('tough-cookie');
var jar = rp.jar();
var links = {
post: 'https://gameforge.com/api/v1/auth/thin/sessions',
accounts: 'https://lobby.ogame.gameforge.com/api/users/me/accounts'
};
login_post_options = {
method: 'POST',
uri: links.post,
headers: {'User-Agent': user_agent},
form: {
'identity': 'en.gb.scraper@gmail.com',
'password': 'Scraper12345',
'locale': 'de_DE',
'gfLang': 'de',
'platformGameId': '1dfd8e7e-6e1a-4eb1-8c64-03c3b62efd2f',
'gameEnvironmentId': '0a31d605-ffaf-43e7-aa02-d06df7116fc8',
'autoGameAccountCreation': 'false'
},
jar: jar,
resolveWithFullResponse: true,
json: true
};
get_options = {
accounts: {
method: 'GET',
uri: links.accounts,
headers: {
'User-Agent': user_agent,
'Authorization': null
},
followAllRedirects: false,
jar: jar,
resolveWithFullResponse: true,
json: true
}
};
async function set_authorization_token(token) {
get_options.accounts.headers.Authorization = 'Bearer ' + token;
};
async function get_accounts () {
try {
//first post request - 1st step login
let post = await rp(login_post_options)
set_authorization_token(post.body.token);
//get all the accounts
let account = await rp(get_options.accounts);
return account.body;
}
catch (error) {
console.log(error);
};
};
get_accounts().then(result => console.dir(result,{depth: null}));