How to get a Minecraft session ID? - minecraft

I'm trying to make a Minecraft client and I cant figure out how to get a session ID to start the game. I've done some googling and cant find anyway to get it bar from this answer to Launch Minecraft from command line - username and password as prefix that doesn't work.

Minecraft mc = Minecraft.getMinecraft();
mc.getSession().getToken();

You can manually crash your game by holding down F3 + C. In the crash log will be your session id.

I made a little script that returns the session id.
def GetSessionID(Username, Password):
# Url = f'https://login.minecraft.net?user={Username}&password={Password}&version=13'
Url = "https://authserver.mojang.com/authenticate"
# LoginInfo = requests.post(Url)
# LoginInfoList = LoginInfo.split(':')
# SessionID = LoginInfoList[3]
token = str(uuid.uuid4())
requestData = GetAuthenticationBody(Username, Password, token)
response = requests.post(url=Url, json=requestData)
responseData = response.json()
SessionID = responseData['accessToken']
return SessionID
def GetAuthenticationBody(username, password, token):
body = {
"agent": {
"name": "Minecraft",
"version": 1
},
"username": username,
"password": password,
"clientToken": token,
"requestUser": True
}
return body

Related

Kraken API authentication sample converted from python to Google apps script is not returning the same output

I am trying to convert python kraken API auth to Google Script to use it in a Google Spreadsheet, but with no luck.
# python sample
def get_kraken_signature(urlpath, data, secret):
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()
message = urlpath.encode() + hashlib.sha256(encoded).digest()
mac = hmac.new(base64.b64decode(secret), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())
return sigdigest.decode()
api_sec = "kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F1huXg=="
data = {
"nonce": "1616492376594",
"ordertype": "limit",
"pair": "XBTUSD",
"price": 37500,
"type": "buy",
"volume": 1.25
}
signature = get_kraken_signature("/0/private/AddOrder", data, api_sec)
print("API-Sign: {}".format(signature))
# prints API-Sign: 4/dpxb3iT4tp/ZCVEwSnEsLxx0bqyhLpdfOpc6fn7OR8+UClSV5n9E6aSS8MPtnRfp32bAb0nmbRn6H8ndwLUQ==
I ended up with this, but it's not returning the same output.
# google script sample from my sheet
function get_kraken_sinature(url, data, nonce, secret) {
var message = url + Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, Utilities.base64Encode(nonce + data));
var base64Secret = Utilities.base64Decode(secret);
var mac = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, message, secret);
return Utilities.base64Encode(mac);
}
signature = get_kraken_signature("/0/private/AddOrder", data, api_sec)
print("API-Sign: {}".format(signature))
# prints API-Sign: Jn6Zk8v41uvMWOY/RTBTrb7zhGxyAOTclFFe7lySodBnEnXErfJgIcQb90opFwccuKDd0Nt1l71HT3V9+P8pUQ==
Both code samples should do the same, and are supposed to output an identical API-Sign key. They are not at this stage, and I am wondering why is that.
I believe your goal is as follows.
You want to convert your python script to Google Apps Script.
In your Google Apps Script, you have already confirmed that the script for requesting works fine. You want to convert get_kraken_signature of your python script to Google Apps Script.
In this case, how about the following modified script?
Modified script:
function get_kraken_sinature(url, data, nonce, secret) {
var str = Object.entries(data).map(([k, v]) => `${k}=${v}`).join("&");
var message = Utilities.newBlob(url).getBytes().concat(Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, nonce + str));
var mac = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, message, Utilities.base64Decode(secret));
return Utilities.base64Encode(mac);
}
// Please run this function.
function main() {
const data = {
"nonce": "1616492376594",
"ordertype": "limit",
"pair": "XBTUSD",
"price": 37500,
"type": "buy",
"volume": 1.25
};
var url = "/0/private/AddOrder";
var nonce = "1616492376594";
var secret = "kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F1huXg==";
var res = get_kraken_sinature(url, data, nonce, secret);
console.log(res)
}
References:
computeDigest(algorithm, value)
computeHmacSignature(algorithm, value, key)

App-Only Token Fetches Users But Can't Create Subscriptions?

I am using an "app-only" token to retrieve my users which works just fine.
Once the app loops through the users, it's supposed to create a subscription as shown below.
However, when attempting to create the subscription, the request simply returns:
Code: InvalidRequest Message: Unable to connect to the remote server
Inner error
My question is, why does the subscription request fail to connect when I am obviously able to successfully connect in the first request which retrieves the users?
How can I see the inner error?
string tenantId = appSettings.TenantId;
var client = sdkHelper.GetAuthenticatedClientAppOnly(tenantId);
// this request works...
IGraphServiceUsersCollectionPage users = await client.Users.Request().Filter("userPrincipalName eq 'MY_USER_PRINCIPAL_NAME'").GetAsync();
if (users?.Count > 0)
{
foreach (User user in users)
{
// this request doesn't work...
Subscription newSubscription = new Subscription();
string clientState = Guid.NewGuid().ToString();
newSubscription = await client.Subscriptions.Request().AddAsync(new Subscription
{
Resource = $"users/{ user.Id }#{ tenantId }/mailFolders('Inbox')/messages",
//Resource = $"users/{ user.UserPrincipalName }/mailFolders('Inbox')/messages", // also tried using email address
ChangeType = "created",
NotificationUrl = "https://localhost:44334/notification/listen",
ClientState = clientState,
//ExpirationDateTime = DateTime.UtcNow + new TimeSpan(0, 0, 4230, 0) // current maximum lifespan for messages
ExpirationDateTime = DateTime.UtcNow + new TimeSpan(0, 0, 15, 0) // shorter duration useful for testing
});
}
}
When I wrap the call in a try/catch, the error message is just this with no inner exception:
Exception of type 'Microsoft.Graph.ServiceException' was thrown.
I have tried all three resources URLs but all result in the same error as shown above:
Resource = $"users/{ user.Id }/mailFolders('Inbox')/messages",
Resource = $"users/{ user.Id }#{ tenantId }/mailFolders('Inbox')/messages",
Resource = $"users/{ user.UserPrincipalName }/mailFolders('Inbox')/messages",
I found this thread on github but the requests don't seem to work for me.
Allow Application-Only requests to create subscriptions - https://github.com/microsoftgraph/microsoft-graph-docs/issues/238
NotificationUrl cannot be "localhost!" The request is being sent from a remote server so it has no idea what localhost would be thus it fails. If I deploy my project to a remote server and pass the URL, it will likely work. I will try that...

matching and verifying Express 3/Connect 2 session keys from socket.io connection

I have a good start on a technique similar to this in Express 3
http://notjustburritos.tumblr.com/post/22682186189/socket-io-and-express-3
the idea being to let me grab the session object from within a socket.io connection callback, storing sessions via connect-redis in this case.
So, in app.configure we have
var db = require('connect-redis')(express)
....
app.configure(function(){
....
app.use(express.cookieParser(SITE_SECRET));
app.use(express.session({ store: new db }));
And in the app code there is
var redis_client = require('redis').createClient()
io.set('authorization', function(data, accept) {
if (!data.headers.cookie) {
return accept('Sesssion cookie required.', false)
}
data.cookie = require('cookie').parse(data.headers.cookie);
/* verify the signature of the session cookie. */
//data.cookie = require('cookie').parse(data.cookie, SITE_SECRET);
data.sessionID = data.cookie['connect.sid']
redis_client.get(data.sessionID, function(err, session) {
if (err) {
return accept('Error in session store.', false)
} else if (!session) {
return accept('Session not found.', false)
}
// success! we're authenticated with a known session.
data.session = session
return accept(null, true)
})
})
The sessions are being saved to redis, the keys look like this:
redis 127.0.0.1:6379> KEYS *
1) "sess:lpeNPnHmQ2f442rE87Y6X28C"
2) "sess:qsWvzubzparNHNoPyNN/CdVw"
and the values are unencrypted JSON. So far so good.
The cookie header, however, contains something like
{ 'connect.sid': 's:lpeNPnHmQ2f442rE87Y6X28C.obCv2x2NT05ieqkmzHnE0VZKDNnqGkcxeQAEVoeoeiU' }
So now the SessionStore and the connect.sid don't match, because the signature part (after the .) is stripped from the SessionStore version.
Question is, is is safe to just truncate out the SID part of the cookie (lpeNPnHmQ2f442rE87Y6X28C) and match based on that, or should the signature part be verified? If so, how?
rather than hacking around with private methods and internals of Connect, that were NOT meant to be used this way, this NPM does a good job of wrapping socket.on in a method that pulls in the session, and parses and verifies
https://github.com/functioncallback/session.socket.io
Just use cookie-signature module, as recommended by the comment lines in Connect's utils.js.
var cookie = require('cookie-signature');
//assuming you already put the session id from the client in a var called "sid"
var sid = cookies['connect.sid'];
sid = cookie.unsign(sid.slice(2),yourSecret);
if (sid == "false") {
//cookie validation failure
//uh oh. Handle this error
} else {
sid = "sess:" + sid;
//proceed to retrieve from store
}

Google task API authentication issue ruby

I am having the problem to authenticate a user for google tasks.
At first it authenticates the user and do things perfect. But in the second trip it throws an error.
Signet::AuthorizationError - Authorization failed. Server message:
{
"error" : "invalid_grant"
}:
following is the code:
def api_client code=""
#client ||= (begin
client = Google::APIClient.new
client.authorization.client_id = settings.credentials["client_id"]
client.authorization.client_secret = settings.credentials["client_secret"]
client.authorization.scope = settings.credentials["scope"]
client.authorization.access_token = "" #settings.credentials["access_token"]
client.authorization.redirect_uri = to('/callbackfunction')
client.authorization.code = code
client
end)
end
get '/callbackfunction' do
code = params[:code]
c = api_client code
c.authorization.fetch_access_token!
result = c.execute("tasks.tasklists.list",{"UserId"=>"me"})
unless result.response.status == 401
p "#{JSON.parse(result.body)}"
else
redirect ("/oauth2authorize")
end
end
get '/oauth2authorize' do
redirect api_client.authorization.authorization_uri.to_s, 303
end
What is the problem in performing the second request?
UPDATE:
This is the link and parameters to user consent.
https://accounts.google.com/o/oauth2/auth?
access_type=offline&
approval_prompt=force&
client_id=somevalue&
redirect_uri=http://localhost:4567/oauth2callback&
response_type=code&
scope=https://www.googleapis.com/auth/tasks
The problem is fixed.
Solution:
In the callbackfunction the tokens which are received through the code provided by the user consent are stored in the database.
Then in other functions just retrieve those tokens from the database and use to process whatever you want against the google task API.
get '/callbackfunction' do
code = params[:code]
c = api_client code
c.authorization.fetch_access_token!
# store the tokens in the database.
end
get '/tasklists' do
# Retrieve the codes from the database and create a client
result = client.execute("tasks.tasklists.list",{"UserId"=>"me"})
unless result.response.status == 401
p "#{JSON.parse(result.body)}"
else
redirect "/oauth2authorize"
end
end
I am using rails, and i store the token only inside DB.
then using a script i am setting up new client before calling execute, following is the code.
client = Google::APIClient.new(:application_name => 'my-app', :application_version => '1.0')
client.authorization.scope = 'https://www.googleapis.com/auth/analytics.readonly'
client.authorization.client_id = Settings.ga.app_key
client.authorization.client_secret = Settings.ga.app_secret
client.authorization.access_token = auth.token
client.authorization.refresh_token = true
client.authorization.update_token!({access_token: auth.token})
client.authorization.fetch_access_token!
if client.authorization.refresh_token && client.authorization.expired?
client.authorization.fetch_access_token!
end
puts "Getting accounts list..."
result = client.execute(:api_method => analytics.management.accounts.list)
puts " ===========> #{result.inspect}"
items = JSON.parse(result.response.body)['items']
But,it gives same error you are facing,
/signet-0.4.5/lib/signet/oauth_2/client.rb:875:in `fetch_access_token': Authorization failed. Server message: (Signet::AuthorizationError)
{
"error" : "invalid_grant"
}
from /signet-0.4.5/lib/signet/oauth_2/client.rb:888:in `fetch_access_token!'
Please suggest why it is not able to use the given token? I have used oauth2, so user is already authorized. Now i want to access the api and fetch the data...
===================UPDATE ===================
Ok, two issues were there,
Permission is to be added to devise.rb,
config.omniauth :google_oauth2, Settings.ga.app_key,Settings.ga.app_secret,{
access_type: "offline",
approval_prompt: "" ,
:scope => "userinfo.email, userinfo.profile, plus.me, analytics.readonly"
}
refresh_token must be passed to the API call, otherwise its not able to authorize.
I hope this helps to somebody, facing similar issue.

Google Reader API Unread Count

Does Google Reader have an API and if so, how can I get the count of the number of unread posts for a specific user knowing their username and password?
This URL will give you a count of unread posts per feed. You can then iterate over the feeds and sum up the counts.
http://www.google.com/reader/api/0/unread-count?all=true
Here is a minimalist example in Python...parsing the xml/json and summing the counts is left as an exercise for the reader:
import urllib
import urllib2
username = 'username#gmail.com'
password = '******'
# Authenticate to obtain SID
auth_url = 'https://www.google.com/accounts/ClientLogin'
auth_req_data = urllib.urlencode({'Email': username,
'Passwd': password,
'service': 'reader'})
auth_req = urllib2.Request(auth_url, data=auth_req_data)
auth_resp = urllib2.urlopen(auth_req)
auth_resp_content = auth_resp.read()
auth_resp_dict = dict(x.split('=') for x in auth_resp_content.split('\n') if x)
auth_token = auth_resp_dict["Auth"]
# Create a cookie in the header using the SID
header = {}
header['Authorization'] = 'GoogleLogin auth=%s' % auth_token
reader_base_url = 'http://www.google.com/reader/api/0/unread-count?%s'
reader_req_data = urllib.urlencode({'all': 'true',
'output': 'xml'})
reader_url = reader_base_url % (reader_req_data)
reader_req = urllib2.Request(reader_url, None, header)
reader_resp = urllib2.urlopen(reader_req)
reader_resp_content = reader_resp.read()
print reader_resp_content
And some additional links on the topic:
http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI
How do you access an authenticated Google App Engine service from a (non-web) python client?
http://blog.gpowered.net/2007/08/google-reader-api-functions.html
It is there. Still in Beta though.
Here is an update to this answer
import urllib
import urllib2
username = 'username#gmail.com'
password = '******'
# Authenticate to obtain Auth
auth_url = 'https://www.google.com/accounts/ClientLogin'
#auth_req_data = urllib.urlencode({'Email': username,
# 'Passwd': password})
auth_req_data = urllib.urlencode({'Email': username,
'Passwd': password,
'service': 'reader'})
auth_req = urllib2.Request(auth_url, data=auth_req_data)
auth_resp = urllib2.urlopen(auth_req)
auth_resp_content = auth_resp.read()
auth_resp_dict = dict(x.split('=') for x in auth_resp_content.split('\n') if x)
# SID = auth_resp_dict["SID"]
AUTH = auth_resp_dict["Auth"]
# Create a cookie in the header using the Auth
header = {}
#header['Cookie'] = 'Name=SID;SID=%s;Domain=.google.com;Path=/;Expires=160000000000' % SID
header['Authorization'] = 'GoogleLogin auth=%s' % AUTH
reader_base_url = 'http://www.google.com/reader/api/0/unread-count?%s'
reader_req_data = urllib.urlencode({'all': 'true',
'output': 'xml'})
reader_url = reader_base_url % (reader_req_data)
reader_req = urllib2.Request(reader_url, None, header)
reader_resp = urllib2.urlopen(reader_req)
reader_resp_content = reader_resp.read()
print reader_resp_content
Google Reader removed SID auth around June, 2010 (I think), using new Auth from ClientLogin is the new way and it's a bit simpler (header is shorter). You will have to add service in data for requesting Auth, I noticed no Auth returned if you don't send the service=reader.
You can read more about the change of authentication method in this thread.
In the API posted in [1], the "token" field should be "T"
[1] http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI