Skip to content

Instantly share code, notes, and snippets.

@rithvikvibhu
Last active June 23, 2024 09:54
Show Gist options
  • Save rithvikvibhu/952f83ea656c6782fbd0f1645059055d to your computer and use it in GitHub Desktop.
Save rithvikvibhu/952f83ea656c6782fbd0f1645059055d to your computer and use it in GitHub Desktop.
Get tokens for Google Home Foyer API

Get tokens for Google Home Foyer API

Intro

This script (python 3) generates tokens that can be used when making requests to the Google Home Foyer API. There are 2 kinds of tokens used here:

  1. Master token - Is in the form aas_et/*** and is long lived. Needs Google username and password.
  2. Access token - Is in the form ya29.*** and lasts for an hour. Needs Master token to generate.

If you do not want to store the Google account password in plaintext, get the master token once, and set it as an override value.

It's safer/easier to generate an app password and use it instead of the actual password. It still has the same access as the regular password, but still better than using the real password while scripting. (https://myaccount.google.com/apppasswords)

Usage

# Install python requirements
pip install gpsoauth

# Update the constants at the beginning of the file

# Get the tokens!
python3 get_tokens.py
# Get tokens for Google Home Foyer API
# https://gist.github.com/rithvikvibhu/952f83ea656c6782fbd0f1645059055d
from gpsoauth import perform_master_login, perform_oauth
from uuid import getnode as getmac
# Creds to use when logging in
USERNAME = '<google_username>'
PASSWORD = '<google_password_or_app_password>'
# Optional Overrides (Set to None to ignore)
device_id = None
master_token = None
access_token = None
# Flags
DEBUG = False
def get_master_token(username, password, android_id):
res = perform_master_login(username, password, android_id)
if DEBUG:
print(res)
if 'Token' not in res:
print('[!] Could not get master token.')
return None
return res['Token']
def get_access_token(username, master_token, android_id):
res = perform_oauth(
username, master_token, android_id,
app='com.google.android.apps.chromecast.app',
service='oauth2:https://www.google.com/accounts/OAuthLogin',
client_sig='24bb24c05e47e0aefa68a58a766179d9b613a600'
)
if DEBUG:
print(res)
if 'Auth' not in res:
print('[!] Could not get access token.')
return None
return res['Auth']
def _get_android_id():
mac_int = getmac()
if (mac_int >> 40) % 2:
raise OSError("a valid MAC could not be determined."
" Provide an android_id (and be"
" sure to provide the same one on future runs).")
android_id = _create_mac_string(mac_int)
android_id = android_id.replace(':', '')
return android_id
def _create_mac_string(num, splitter=':'):
mac = hex(num)[2:]
if mac[-1] == 'L':
mac = mac[:-1]
pad = max(12 - len(mac), 0)
mac = '0' * pad + mac
mac = splitter.join([mac[x:x + 2] for x in range(0, 12, 2)])
mac = mac.upper()
return mac
if not device_id:
device_id = _get_android_id()
print('''
This script generates tokens that can be used when making requests to the Google Home Foyer API.
There are 2 kinds of tokens used here:
1. Master token - Is in the form `aas_et/***` and is long lived. Needs Google username and password.
2. Access token - Is in the form `ya29.***` and lasts for an hour. Needs Master token to generate.
If you do not want to store the Google account password in plaintext,
get the master token once, and set it as an override value.
It's safer/easier to generate an app password and use it instead of the actual password.
It still has the same access as the regular password, but still better than using the real password while scripting.
(https://myaccount.google.com/apppasswords)
''')
print('\n[*] Getting master token...')
if not master_token:
master_token = get_master_token(USERNAME, PASSWORD, device_id)
print('[*] Master token:', master_token)
print('\n[*] Getting access token...')
if not access_token:
access_token = get_access_token(USERNAME, master_token, device_id)
print('[*] Access token:', access_token)
print('\n[*] Done.')
MIT License
Copyright (c) 2020 Rithvik Vibhu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@rithvikvibhu
Copy link
Author

That's awesome 💯! Will try it out soon and link to it from this gist and on the website.

@leikoilja
Copy link

@rithvikvibhu, yay, managed to pack it into the python package. Thanks for the help.
All the testing are much appreciated

@cicero200272
Copy link

I am requested to log in (using a browser) first. When I copy & paste the URL to a browser window, I can provide my credentials, but then I am stuck on a "One moment please..." page which does not reload. Does anybody else have this kind of problem?

@rithvikvibhu
Copy link
Author

Not sure what you mean @cicero200272. Which URL did you copy? This script doesn't need any browser or a website to visit at all.

@cicero200272
Copy link

screen1

@rithvikvibhu
Copy link
Author

@cicero200272 Let's move to an issue rithvikvibhu/GHLocalApi#71

@ArnyminerZ
Copy link

Thank you, @rithvikvibhu.

I have written a small script in python that is extracting the local authentication tokens.
https://github.com/leikoilja/glocaltokens.

If helpful you can maybe include it in the https://rithvikvibhu.github.io/GHLocalApi/ documentation :)

Just wanted to thank you very much for your work. Loading the device's JSON had me crazy for some days :)

@Shonke
Copy link

Shonke commented Dec 13, 2022

@ArnyminerZ After investigation, i found that this may be related to tls fingerprints. I use this to work for me:
https://github.com/akinazuki/google_aas_et_generate/blob/84c6ca6/aas_et.go#L41

@bagelos
Copy link

bagelos commented Mar 6, 2023

Hi
I am getting a weird error running this - whilst trying to resolve goog-home integration with homeassistant.

Ubuntu 22.04 and python 3.11. Latest available @ 2023-Mar-06

Traceback (most recent call last):
File "/home/homeassistant/get_tokens.py", line 70, in
device_id = _get_android_id()
^^^^^^^^^^^^^^^^^
File "/home/homeassistant/get_tokens.py", line 49, in _get_android_id
raise OSError("a valid MAC could not be determined."
OSError: a valid MAC could not be determined. Provide an android_id (and be sure to provide the same one on future runs).

I have used two different app passwords. One where I select Device Other first (and then no option to choose app is available), or app as Other (and then no optiion to choose device).

Versions are :
glocaltokens==0.7.0
gpsoauth==1.0.2
requests==2.28.2
requests-toolbelt==0.10.1
urllib3==1.26.14

If I try a random device_id, I cannot authenticate. Results below.

[] Getting master token...
[!] Could not get master token.
[
] Master token: None

[] Getting access token...
[!] Could not get access token.
[
] Access token: None

thanks
gb

@leikoilja
Copy link

@bagelos, this is wrong place for your issue. What you are seeing is the validation error from glocaltokens library. Please open a new issue ticket here https://github.com/leikoilja/glocaltokens

@bagelos
Copy link

bagelos commented Mar 6, 2023

thanks. will try that. was wondering if the inablity to pick up MAC address was an issue with this script or not.

@jcarlyle
Copy link

thanks. will try that. was wondering if the inablity to pick up MAC address was an issue with this script or not.

This does not seem to be an error from glocaltokens. The call to getmac is an alias for a call to uuid.getnode and getnode is returning a value that is failing the check at line 48. This doesn't seem to involve any calls into glocaltokens.

I tried removing the check and and generating my own 48-bit integer, but I still fail to generate tokens.

Has this script worked for anyone else recently?

@artickl
Copy link

artickl commented Jun 1, 2023

Error: AttributeError: module 'urllib3.util.ssl_' has no attribute 'DEFAULT_CIPHERS'

Fixed by downgrading urllib3 as per simon-weber/gpsoauth#52

pip3 install urllib3\<2

Before it was:

$ python3 get_tokens.py

This script generates tokens that can be used when making requests to the Google Home Foyer API.
There are 2 kinds of tokens used here:

1. Master token - Is in the form `aas_et/***` and is long lived. Needs Google username and password.
2. Access token - Is in the form `ya29.***` and lasts for an hour. Needs Master token to generate.

If you do not want to store the Google account password in plaintext,
get the master token once, and set it as an override value.

It's safer/easier to generate an app password and use it instead of the actual password.
It still has the same access as the regular password, but still better than using the real password while scripting.
(https://myaccount.google.com/apppasswords)


[*] Getting master token...
Traceback (most recent call last):
  File "/home/artickl/git/github/gist/get_tokens.py", line 90, in <module>
    master_token = get_master_token(USERNAME, PASSWORD, device_id)
  File "/home/artickl/git/github/gist/get_tokens.py", line 22, in get_master_token
    res = perform_master_login(username, password, android_id)
  File "/home/artickl/.local/lib/python3.9/site-packages/gpsoauth/__init__.py", line 143, in perform_master_login
    return _perform_auth_request(data, proxy)
  File "/home/artickl/.local/lib/python3.9/site-packages/gpsoauth/__init__.py", line 78, in _perform_auth_request
    session.mount(AUTH_URL, AuthHTTPAdapter())
  File "/home/artickl/.local/lib/python3.9/site-packages/requests/adapters.py", line 155, in __init__
    self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
  File "/home/artickl/.local/lib/python3.9/site-packages/gpsoauth/__init__.py", line 68, in init_poolmanager
    context.set_ciphers(ssl_.DEFAULT_CIPHERS)
AttributeError: module 'urllib3.util.ssl_' has no attribute 'DEFAULT_CIPHERS'

@ProAdmin007
Copy link

Do not name your python file token.py this will create a circular import and the code wil not run!

@Korben85
Copy link

Korben85 commented Jun 6, 2023

I tried downgrading and running the script but
pip install urllib3\<=2
installs the version 2.0.0 which also results in this error
I used
pip install urllib3\<2
instead to install urllib3-1.26.16
The script finishes w/o an error now.
I still got no master token, but that's not the fault of the script, I think.
However, I hope this helps someone else.

@thoompje
Copy link

thoompje commented Jun 7, 2023

Hello All,

The tool won't extract any token, can someone please help! Would be really appreciated.

image

@thoompje
Copy link

anyone?

@leikoilja
Copy link

@thoompje, you can give a try getting master token using https://github.com/leikoilja/glocaltokens package. It does nearly the same as this gist, but has a few extra validation and logic around that might help you identify the issue

@emmaly
Copy link

emmaly commented Jun 19, 2023

I couldn't get this to work in any version of Linux I had on hand, but I did finally get it to run in Windows.

This is what I did (in PowerShell 7.3.4 in Windows):

# make a new Python virtual environment
> python3 -m venv test123

# activate that environment
# ...the Windows way is like this:
> test123\Scripts\activate

# ...but the Linux way would be like this instead:
#> source test123/bin/activate

# install the bare minimum package list without declaring versions
> pip install gpsoauth

# then run the script
> python3 get_token.py

# ...and it failed with this error:
# AttributeError: module 'urllib3.util.ssl_' has no attribute 'DEFAULT_CIPHERS'

# so let's roll the urllib3 package back to whatever newest pre-2.0.0 version we can have...
> pip install urllib3<2.0.0

# and try again
> python3 get_token.py

# ...and then it succeeded!

Here's my version list:

> pip freeze

certifi==2023.5.7
charset-normalizer==3.1.0
gpsoauth==1.0.2
idna==3.4
pycryptodomex==3.18.0
requests==2.31.0
urllib3==1.26.16

Details that would help me if I need this info again:

  • My USERNAME variable had the @gmail.com omitted, so it was just the portion left of the @-symbol.
  • My PASSWORD variable was an Application-Specific Password (ASP), created at https://myaccount.google.com/apppasswords for the account.
  • The ASP was set as "custom" and I named it "Home" but I expect it will have worked no matter what it was named.
  • After failed tests in the script, the "Last used" timestamp was not populated for the ASP, as expected (it stayed set to -).
  • Immediately after the successful run, it immediately was updated to the current time (after a refresh of the ASP page to see that it occurred).
  • I don't think it is likely that Google was blocking the attempts, but simply that it was a version conflict of some kind that happened to work out with the Windows environment.
  • Python installed in this environment is Python 3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)] on win32, which looks like it was installed via winget install Python.Python.3.11
  • I did try https://github.com/leikoilja/glocaltokens in every environment except this Windows one, so it's possible it'll work in this one now, since this worked.

@emmaly
Copy link

emmaly commented Jun 19, 2023

BTW it doesn't work on my machine when trying in Ubuntu 22.04.2 LTS with exactly the same Gmail account (with a new ASP) and using Python 3.10.6 but otherwise using the exact same set of packages as listed previously. It just says Could not get master token instead of blowing up or giving me a valid result.

(test1) emmaly@ubuntu:~/test1$ python3 --version
Python 3.10.6

(test1) emmaly@ubuntu:~/test1$ pip freeze
certifi==2023.5.7
charset-normalizer==3.1.0
gpsoauth==1.0.2
idna==3.4
pycryptodomex==3.18.0
requests==2.31.0
urllib3==1.26.16


(test1) emmaly@ubuntu:~/test1$ python3 get_tokens.py

This script generates tokens that can be used when making requests to the Google Home Foyer API.
There are 2 kinds of tokens used here:

1. Master token - Is in the form `aas_et/***` and is long lived. Needs Google username and password.
2. Access token - Is in the form `ya29.***` and lasts for an hour. Needs Master token to generate.

If you do not want to store the Google account password in plaintext,
get the master token once, and set it as an override value.

It's safer/easier to generate an app password and use it instead of the actual password.
It still has the same access as the regular password, but still better than using the real password while scripting.
(https://myaccount.google.com/apppasswords)


[*] Getting master token...
[!] Could not get master token.
[*] Master token: None

[*] Getting access token...
[!] Could not get access token.
[*] Access token: None

[*] Done.

🤷🏻‍♀️

@biffel
Copy link

biffel commented Jun 19, 2023

I couldn't get this to work in any version of Linux I had on hand, but I did finally get it to run in Windows.

This is what I did (in PowerShell 7.3.4 in Windows):

# make a new Python virtual environment
> python3 -m veth test123

Thanks for taking the time to document this @emmaly . A question and two observations:

  • Did you intend to write instead 'python3 -m venv test123' in that first line? I am not sure what veth is in this context - I may be missing something.
  • I too have been unable to get this to perform correctly on Linix.
  • On Windows (and assuming you meant 'venv'), even after downgrading urllib3 as you did I still get the error AttributeError: module 'urllib3.util.ssl_' has no attribute 'DEFAULT_CIPHERS'. I assume there is something different about my environment but I have not yet worked out what it is.

Brett

@MickLesk
Copy link

MickLesk commented Jul 4, 2023

ive tried this on my windows computer & live on the raspberry HA system.

always i get an "BadAuthentication",
On the https://myaccount.google.com/apppasswords page my app password is displayed (Called: "HomeAssistant") but it has never been retrieved, so apparently it fails already at the general call.

I have tested the following:
Username: my.email@gmail.com (Fake-Address)
Username: my.email (fake address)
Password: My real password
Password: My app password

I have played through all constellations, apparently the script fails directly on execution / before login.

Here are my examples, various constellations (commented out and censored)

# Creds to use when logging in
USERNAME = 'my.email@gmail.com'
#USERNAME = 'my.email'
#PASSWORD = 'mypassword_censored'
PASSWORD = 'my_apppassword'

# Optional Overrides (Set to None to ignore)
device_id = None
master_token = None
access_token = None

# Flags
DEBUG = True

image

@Korben85
Copy link

Korben85 commented Jul 5, 2023

ive tried this on my windows computer & live on the raspberry HA system.

Have you tried the solution mentioned earlier here?:
https://gist.github.com/rithvikvibhu/952f83ea656c6782fbd0f1645059055d?permalink_comment_id=4603343#gistcomment-4603343

@lpt2007
Copy link

lpt2007 commented Jul 9, 2023

I also get this error I tryed on two different linux machines:

`This script generates tokens that can be used when making requests to the Google Home Foyer API.
There are 2 kinds of tokens used here:

  1. Master token - Is in the form aas_et/*** and is long lived. Needs Google username and password.
  2. Access token - Is in the form ya29.*** and lasts for an hour. Needs Master token to generate.

If you do not want to store the Google account password in plaintext,
get the master token once, and set it as an override value.

It's safer/easier to generate an app password and use it instead of the actual password.
It still has the same access as the regular password, but still better than using the real password while scripting.
(https://myaccount.google.com/apppasswords)

[] Getting master token...
[!] Could not get master token.
[
] Master token: None

[] Getting access token...
[!] Could not get access token.
[
] Access token: None
`

@bagelos
Copy link

bagelos commented Jul 11, 2023

Hi all, likely a python issue but most of what I have seems correct. Error below which is "ModuleNotFoundError: No module named 'gpsoauth'" however pip freeze shows the module is there. Any ideas?

(test1234) PS C:\Users\george> python3 get_token.py
Traceback (most recent call last):
File "C:\Users\george\get_token.py", line 5, in
from gpsoauth import perform_master_login, perform_oauth
ModuleNotFoundError: No module named 'gpsoauth'
(test1234) PS C:\Users\george> pip freeze
certifi==2023.5.7
charset-normalizer==3.2.0
gpsoauth==1.0.2
idna==3.4
pycryptodomex==3.18.0
requests==2.31.0
urllib3==2.0.3
(test1234) PS C:\Users\george> pip install urllib3<2.0.0
Collecting urllib3<2.0.0
Using cached urllib3-1.26.16-py2.py3-none-any.whl (143 kB)
Installing collected packages: urllib3
Attempting uninstall: urllib3
Found existing installation: urllib3 2.0.3
Uninstalling urllib3-2.0.3:
Successfully uninstalled urllib3-2.0.3
Successfully installed urllib3-1.26.16
(test1234) PS C:\Users\george> pip freeze
certifi==2023.5.7
charset-normalizer==3.2.0
gpsoauth==1.0.2
idna==3.4
pycryptodomex==3.18.0
requests==2.31.0
urllib3==1.26.16
(test1234) PS C:\Users\george>

@AustinTiger
Copy link

@emmaly
Thank you so much for your guide! It wasn't until I followed every single step and ensured every single version was the same before I could get it to work on Windows. I could never get it to work on Linux. I had Python 3.9 installed, but even that failed until I updated to 3.11. Thanks again!

@emmaly
Copy link

emmaly commented Jul 17, 2023

I couldn't get this to work in any version of Linux I had on hand, but I did finally get it to run in Windows.
This is what I did (in PowerShell 7.3.4 in Windows):

# make a new Python virtual environment
> python3 -m veth test123

Thanks for taking the time to document this @emmaly . A question and two observations:

  • Did you intend to write instead 'python3 -m venv test123' in that first line? I am not sure what veth is in this context - I may be missing something.
  • I too have been unable to get this to perform correctly on Linix.
  • On Windows (and assuming you meant 'venv'), even after downgrading urllib3 as you did I still get the error AttributeError: module 'urllib3.util.ssl_' has no attribute 'DEFAULT_CIPHERS'. I assume there is something different about my environment but I have not yet worked out what it is.

Brett

Oops, yes, I did mean venv! I mistyped it here, but it was venv when it was done for real. Sorry about that. I've updated my comment that typo won't cause further confusion.

For sure, I never did get it to work in Linux for whatever reason.

Regarding the others... I forget the details. It's frustrating that it's not trivial to resolve!

@artickl
Copy link

artickl commented Jul 18, 2023

It's related to the issue in gpsoauth simon-weber/gpsoauth#48 (comment)

Currently, it's only working on:

  • urllib3==1.26.16 with OpenSSL 1 working fine
  • urllib3-2.0.3 with OpenSSL 1 giving no attribute 'DEFAULT_CIPHERS'
  • urllib3==1.26.16 with OpenSSL 3 giving {'Error': 'BadAuthentication'}
  • urllib3-2.0.3 with OpenSSL 3 giving no attribute 'DEFAULT_CIPHERS'

Unfortunately, downgrading urllib is easy, but openssl not...

You can always check what you have by running the following:

$ dpkg --list | grep -e "openssl " -e "urllib3"
$ pip freeze | grep urllib

@mschabhuettl
Copy link

I've got the same problem.

$ pip freeze
certifi==2023.5.7
charset-normalizer==3.1.0
gpsoauth==1.0.2
idna==3.4
pycryptodomex==3.18.0
requests==2.31.0
urllib3==1.26.16

results in:

[*] Getting master token...
[!] Could not get master token.
[*] Master token: None

[*] Getting access token...
[!] Could not get access token.
[*] Access token: None

[*] Done.

@mschabhuettl
Copy link

Managed to get it working.

  • Setup Debian 11 LXC
  • apt install python3
  • mkdir mastertoken
  • cd mastertoken
  • apt install python3-venv
  • python3 -m venv venv
  • source venv/bin/activate
  • pip install "urllib3<2.0.0"
  • pip install gpsoauth
  • Generated an App Password "gpsoauth" and adapted get_token.py via
  • nano get_token.py (used get_token.py)
USERNAME = 'username@example.com'
PASSWORD = '<GENERATED-APP-PASSWORD>'
  • python3 get_token.py
[*] Getting master token...
[*] Master token: XXX
  • deleted App Password "gpsoauth"
  • Generated an App Password "Google Home Integration for Home Assistant"
  • used this App Password for Integration Setup

Best regards,
Matthias Schabhüttl

@jawilson
Copy link

After a bunch of Googling and reading through comments I was able to get this to work via Docker with the following:

  1. Download get_tokens.py
  2. Update USERNAME to my full email
  3. Update PASSWORD to my app password
  4. Create Dockerfile:
    FROM python:3.9-slim-bullseye
    
    RUN pip install "urllib3<2.0.0" gpsoauth
    COPY ./get_tokens.py ./
    CMD python3 get_tokens.py
    
  5. Run docker build -t get_tokens . && docker run --rm -it get_tokens

Hopefully this should be fully reproducible by everyone.

@dedeweb
Copy link

dedeweb commented Jul 26, 2023

@jawilson thanks a lot, your docker works perfectly :)

@Ammly
Copy link

Ammly commented Aug 2, 2023

Thanks @jawilson

@biffel
Copy link

biffel commented Aug 3, 2023

Thanks @jawilson

@kai5130
Copy link

kai5130 commented Aug 5, 2023

Thanks @jawilson

@SirGoodenough
Copy link

Be prepared for a couple hundred gb docker container to get a couple lines of text...

@oneseventhree
Copy link

oneseventhree commented Sep 12, 2023

thank you! this really helped me a lot @mschabhuettl

@Telmo
Copy link

Telmo commented Sep 17, 2023

I don't know if this will help. I tried multiple scripts/permutations and kept getting the Could Not get token messages. For some reason I decided to edit get_tokens.py in vi/vim and notices that when copying the app password from the google webpage it adds hidden characters. I instead typed the password displayed and this worked.

@AlexInABox
Copy link

Thanks @jawilson

@Prabhakar1980
Copy link

Managed to get it working.

  • Setup Debian 11 LXC
  • apt install python3
  • mkdir mastertoken
  • cd mastertoken
  • apt install python3-venv
  • python3 -m venv venv
  • source venv/bin/activate
  • pip install "urllib3<2.0.0"
  • pip install gpsoauth
  • Generated an App Password "gpsoauth" and adapted get_token.py via
  • nano get_token.py (used get_token.py)
USERNAME = 'username@example.com'
PASSWORD = '<GENERATED-APP-PASSWORD>'
  • python3 get_token.py
[*] Getting master token...
[*] Master token: XXX
  • deleted App Password "gpsoauth"
  • Generated an App Password "Google Home Integration for Home Assistant"
  • used this App Password for Integration Setup

Best regards, Matthias Schabhüttl

Hi ,

how to do this step

Generated an App Password "gpsoauth"

Hopefully the App Password is the above one , i am not sure ?

I have an app password which I used for Password. It is not producing the access token. Below is the output

python3 get_tokens.py

This script generates tokens that can be used when making requests to the Google Home Foyer API.
There are 2 kinds of tokens used here:

  1. Master token - Is in the form aas_et/*** and is long lived. Needs Google username and password.
  2. Access token - Is in the form ya29.*** and lasts for an hour. Needs Master token to generate.
    If you do not want to store the Google account password in plaintext,
    get the master token once, and set it as an override value.
    It's safer/easier to generate an app password and use it instead of the actual password.
    It still has the same access as the regular password, but still better than using the real password while scripting.
    (https://myaccount.google.com/apppasswords)

[] Getting master token...
[!] Could not get master token.
[
] Master token: None

[] Getting access token...
[!] Could not get access token.
[
] Access token: None

[*] Done.

@VNRARA
Copy link

VNRARA commented Sep 27, 2023

I think having a account with passkeys is making this impossible even when making app passwords.

@newstartech
Copy link

I tried a lot. get latest python v3.12.0 installed. run pip install gpsoauth - Ok. copy text of get_tokens.py raw text, saved to my pc. Change username to my google username full email address. password section, tried with app password generated by Google security. (note: it is 16 chars. google displayed with 4 sets with space in between. I tried with space or without). Even I turned off google 2 way auth method, so I can use my google password instead. I always get "Could not get master token", "Master token:None" , "Could not get access token", "Access token:None" don't know why? Anyone can help?

@tophattwaffle
Copy link

Same issue with:

[] Getting master token...
[!] Could not get master token.
[
] Master token: None

[] Getting access token...
[!] Could not get access token.
[
] Access token: None

@DRFR0ST
Copy link

DRFR0ST commented Oct 18, 2023

Try this: leikoilja/ha-google-home#599 (comment)

I have tried all of the suggested solutions and none of them worked, except for the one linked above.

@Frankymuc
Copy link

hi, i have my gogle account name and passwort included this scrpt. if i start its comes:
python3 get_tokens.py
File "/home/frank089/pythonsc/get_tokens.py", line 10
PASSWORD = pasword/
^
SyntaxError: invalid syntax

if the / not working with this scipt? must i change my google password an all on google account aps using google passwort?

@CaliLuke
Copy link

same story as above, I cannot get the script to work. I also have passkeys enabled, I tried using both my actual password and two different application passwords just in case.

@Nemesis24
Copy link

Hi, this is the same for me

@cjsturgess
Copy link

For anyone still facing an issue with this script, see this comment: leikoilja/ha-google-home#599 (comment)

Worked for me, first try.

@molexx
Copy link

molexx commented Feb 4, 2024

I got the double whammy here: the app password copy/paste from the Google website does indeed contain hidden characters; after I retyped that I tried several scripts (in homeassistant's terminal) and must be hitting the library issue, so retyped in the dockerised script is the way to go.

The docker command in the main readme is slicker than the one in the comment linked above as it does it all on one line.

https://github.com/leikoilja/ha-google-home?tab=readme-ov-file#master-token

So thanks @Telmo and @Brephlas !

@jnpetersen
Copy link

utilizing the link that @molexx shared, I ended up modifying the docker run slightly so that I could get inside the container to make a few changes to the python itself.

docker run -it -d breph/ha-google-home_get-token

After it created, I did a docker ps to find the name of the container (I tried providing a name and it would always fail). Once this was created, I used the following:

docker exec -it tender_gates bash

tender_gates being the name it generated for me, but once running this, I was in the container.

I ran apt install nano just to make it easier to work with and then ran nano get_tokens.py to open the file. I commented out

USERNAME = input("what is your google mail address? (include @gmail.com): ")
PASSWORD = input("what is the password? (either use regular password or app password): ")

and replacing it with

USERNAME = '<FULL GMAIL EMAIL ADDRESS>'
PASSWORD = '<APP PASSWORD COPIED AND PASTED FROM GOOGLE>'

After making this change, press Ctrl + O and then press enter to Save the changes, then press Ctrl + X to exit nano.

When I ran it in the container by typing python3 get_tokens.py, I thought that was going to work but kept getting [!] Could not get master token. so I decided to change DEBUG = False to DEBUG = True, saved and exited nano again and ran it again and was provided:

[*] Getting master token...
{'Error': 'NeedsBrowser', 'Url': 'https://accounts.google.com/signin/continue?sarp=1&scc=1&continue=https://accounts.google.com/o/android/auth?hl%3Den_us%26xoauth_display_name%3DAndroid%2BLogin%2BService%26source%3DAndroid%2BLogin&plt=[... truncated ...]', 'ErrorDetail': 'To access your account, you must sign in on the web. Touch Next to start browser sign-in.'}
[!] Could not get master token.
[*] Master token: None

PROGRESS!! I held down Control and clicked the link which brought me to a browser to finish the authentication process from the web browser to authenticate the script to work. You may have to go through a few prompts (I did) and then it will end up at a page that says One Moment Please..., which at this point you can re-run python3 get_token.py and it should provide you with a lot more information than just the master and access tokens as DEBUG is still on, but you should be provided with the information needed.

Hope this helps someone.

@edx-sayed-salem
Copy link

edx-sayed-salem commented Mar 17, 2024

installing gpsoauth==1.0.2 seems to work ok. Newer versions return the NeedsBrowser error.

Update
It also only worked on docker images based on: debian:bullseye and alpine:3.16. I didn't try below these versions but newer than those don't work. The openssl package version is 1.1.1 on debian:bullseye and alpine:3.16. Newer versions had version >3.0.0 like @artickl said.

@lcamus
Copy link

lcamus commented Mar 31, 2024

Thank you! I just needed indeed to downgrade gpsoauth to 1.0.2 (previously install 1.0.4) to get rid of the NeedsBrowser error.
pip freeze
pip uninstall gpsoauth
pip install gpsoauth==1.0.2

@ulasozguler
Copy link

Thanks. I can confirm using specific version of packages like this works:

FROM python:3.9-slim-bullseye
RUN pip install "urllib3<2.0.0" "gpsoauth==1.0.2"
COPY ./get_tokens.py ./
CMD python3 get_tokens.py
docker build -t get_tokens . && docker run --rm -it get_tokens

@MauGianfa
Copy link

MauGianfa commented Apr 22, 2024

Hi,
I'v enabled debug on the script and get this error:

] Getting master token...
{'Error': 'BadAuthentication'}
[!] Could not get master token.
[
] Master token: None

[] Getting access token...
{'Error': 'BadAuthentication'}
[!] Could not get access token.
[
] Access token: None

[*] Done.

Checked username and password many times are CORRECT. Created different app password, tried the account password but still get this error!!!
What am I missing out?

Thanks

@lcamus
Copy link

lcamus commented Apr 22, 2024

If you use an application password and just copy-paste it from the Google screen, take care to remove the extra space or hyphens that are not part of the password.

@MauGianfa
Copy link

Hi,
Yes I did.... Any other idea?

@edx-sayed-salem
Copy link

@MauGianfa , I just tried this (from a few comments ago) and it's fine. Did you try it?

Thanks. I can confirm using specific version of packages like this works:

FROM python:3.9-slim-bullseye
RUN pip install "urllib3<2.0.0" "gpsoauth==1.0.2"
COPY ./get_tokens.py ./
CMD python3 get_tokens.py
docker build -t get_tokens . && docker run --rm -it get_tokens

@emmaly
Copy link

emmaly commented May 5, 2024

@MauGianfa , I just tried this (from a few comments ago) and it's fine. Did you try it?

Thanks. I can confirm using specific version of packages like this works:

FROM python:3.9-slim-bullseye
RUN pip install "urllib3<2.0.0" "gpsoauth==1.0.2"
COPY ./get_tokens.py ./
CMD python3 get_tokens.py
docker build -t get_tokens . && docker run --rm -it get_tokens

This worked great. Humorously enough, I was facing this issue in June 2023 (last year) as you can see in my previous comments on this gist, I came back here and found the solution that worked the fastest. Thank you!

@shayaantx
Copy link

shayaantx commented May 28, 2024

urllib3<2.0.0 seems to install 1.26.18 which doesn't work for me for some reason

hardcoding to 1.25.1 seems to work currently

@Coax88
Copy link

Coax88 commented Jun 3, 2024

I get this error

Traceback (most recent call last): File "//get_tokens.py", line 90, in <module> master_token = get_master_token(USERNAME, PASSWORD, device_id) File "//get_tokens.py", line 22, in get_master_token res = perform_master_login(username, password, android_id) File "/usr/local/lib/python3.9/site-packages/gpsoauth/__init__.py", line 155, in perform_master_login return _perform_auth_request(data, proxy) File "/usr/local/lib/python3.9/site-packages/gpsoauth/__init__.py", line 98, in _perform_auth_request res = session.post(AUTH_URL, data=data, verify=True) File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 637, in post return self.request("POST", url, data=data, json=json, **kwargs) File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 698, in send raise SSLError(e, request=request) requests.exceptions.SSLError: HTTPSConnectionPool(host='android.clients.google.com', port=443): Max retries exceeded with url: /auth (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1133)')))

@tdeboss
Copy link

tdeboss commented Jun 4, 2024

I have the same error ad @Coax88

@Coax88
Copy link

Coax88 commented Jun 5, 2024

I tried with the docker instead now i get this, have tried login on the browser and run the script again, then it says the same

[*] Getting master token...
{'Error': 'NeedsBrowser', 'Url': 'https://accounts.google.com/signin/continue?sarp=1&scc=1&continue=https://accounts.google.com/o/android/auth?hl%3Den_us%26xoauth_display_name%3DAndroid%2BLogin%2BService%26source%3DAndroid%2BLogin&plt=AKgnsbuZ_w9LYv1eVbP_S1pKbz26IzgW1FHtqj9n_O5K0S2sMMlgsP8F85yrgPZQZdqoUBcUM32wl-rlhZnk1Ee4MyZ-HClGWMW1JwUdvqFHh50NsRhMo1w43dyh1mZkeqmMRBi4zp6j', 'ErrorDetail': 'To access your account, you must sign in on the web. Touch Next to start browser sign-in.'}
[!] Could not get master token.
[*] Master token: None

[*] Getting access token...
{'Error': 'BadAuthentication'}
[!] Could not get access token.
[*] Access token: None

[*] Done.
root@docker:~# `
``

@r74tech
Copy link

r74tech commented Jun 6, 2024

Thanks. I can confirm using specific version of packages like this works:

FROM python:3.9-slim-bullseye
RUN pip install "urllib3<2.0.0" "gpsoauth==1.0.2"
COPY ./get_tokens.py ./
CMD python3 get_tokens.py
docker build -t get_tokens . && docker run --rm -it get_tokens
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 597, in urlopen
    httplib_response = self._make_request(conn, method, url,
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 343, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 839, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 337, in connect
    self.sock = ssl_wrap_socket(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 345, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/local/lib/python3.9/ssl.py", line 501, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/local/lib/python3.9/ssl.py", line 1074, in _create
    self.do_handshake()
  File "/usr/local/lib/python3.9/ssl.py", line 1343, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1133)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 667, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 637, in urlopen
    retries = retries.increment(method, url, error=e, _pool=self,
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/retry.py", line 399, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='android.clients.google.com', port=443): Max retries exceeded with url: /auth (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1133)')))

Looking at the threads here, I wonder if it was working until last week.

I couldn't use it, but I was able to do it using the method you showed me here, so I'll just note it.
leikoilja/glocaltokens#531

https://github.com/leikoilja/ha-google-home#master-token

@gw72
Copy link

gw72 commented Jun 8, 2024

What are the security implications of using a master token? Can anyone use that to access my whole google account at any time? Can access using the token be revoked?

@PietroSpina
Copy link

https://gist.github.com/rithvikvibhu/952f83ea656c6782fbd0f1645059055d?permalink_comment_id=4793755#gistcomment-4793755

So the folks like @CaliLuke @Nemesis24 that got their Master Tokens but had trouble putting them into the integration config window... did it ever work? what's the trick?

FWIW if I run the script multiple times, I get different master tokens every time

@edx-sayed-salem
Copy link

If anyone is getting urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='android.clients.google.com', port=443): Max retries exceeded with url: /auth (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)'))) like me and @r74tech

I cleared it by using Mozilla CA certificate from curl

I added this after the imports to force python to use this cert instead of default (you can modify this to download the cert somewhere else if you like, I use it in a container so I don't bother):

import urllib.request

# Download the SSL certificate
urllib.request.urlretrieve('https://curl.se/ca/cacert.pem', 'cacert.pem')

# Set downloaded cert to be used
os.environ['CURL_CA_BUNDLE'] = f'{os.getcwd()}/cacert.pem'

Hope it helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment