Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to login anymore - firstly got reported as pickle is invalid #524

Open
nat2k5us opened this issue Dec 21, 2024 · 11 comments
Open

Unable to login anymore - firstly got reported as pickle is invalid #524

nat2k5us opened this issue Dec 21, 2024 · 11 comments

Comments

@nat2k5us
Copy link

nat2k5us commented Dec 21, 2024

Unable to login anymore - firstly got reported as pickle is invalid
Then after many attempts still not able to get past the key error when using the simple login method

I have 2FA enabled with the authenticator app - so when the login/pikle has expired I would get prompted to enter the authenticator app code in the console - but now that is no longer is happening

The client id is being reported as invalid - is there a new client id - how to get a valid id?

Thank you

import os
import requests
import pyotp


### Replace the endpoint with the correct one if necessary
url = "https://api.robinhood.com/oauth2/token/"
totp  = pyotp.TOTP("My2factorAppHere").now()
print(f"    TOTP: {totp}")
payload = {
    "username": os.getenv("RH_USERNAME"),
    "password": os.getenv("RH_PASSWORD"),
    "mfa_code": totp,
    "grant_type": "password",
    "scope": "internal",
    "client_id": "c82SH0WZNTt8bRhZR4B0RQvmfxo3x10c",
}

response = requests.post(url, data=payload)
print(response.json())  # Inspect the API response

Gives the error
    TOTP: xxxxxxx
{'error': 'invalid_client'}

Second way:


def login_to_robinhood():
    username = os.getenv("RH_USERNAME")
    password = os.getenv("RH_PASSWORD")
    if not username or not password:
        print("Error: RH_USERNAME or RH_PASSWORD environment variables are not set.")
        return
    logged_in = r.login(username, password)
    print(f"Login: {logged_in}")
    return logged_in

got these error
File "/Users/xxxxxx/dev/rh/myprofits/libs/robin_stocks/robin_stocks/robinhood/authentication.py", line 190, in login
raise Exception(data['detail'])
Exception: Unable to log in with provided credentials.

@nat2k5us
Copy link
Author

I used the authenticator App and the latest robin_stock code and that looks to have solved the issue

import os
import pyotp
import argparse
import robin_stocks.robinhood as r


def generate_token():
    totp = pyotp.TOTP("My2factorAppHere").now()
    print(f"TOTP: {totp}")

def login(mfa_code):
    username = os.getenv("RH_USERNAME")
    password = os.getenv("RH_PASSWORD")
    if not username or not password:
        print("Error: RH_USERNAME or RH_PASSWORD environment variables are not set.")
        exit(1)
    # Add your login logic here
    print(f"User parameter: {mfa_code}")
    login = r.login(username, password, mfa_code=mfa_code)
    print(f"Login: {login}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Process command line arguments.")
    parser.add_argument("action", choices=["token", "login"], help="Action to perform: 'token' or 'login'")
    parser.add_argument("mfa_code", nargs='?', help="User parameter for login action")
    args = parser.parse_args()

    if args.action == "token":
        generate_token()
    elif args.action == "login":
        if args.mfa_code:
            login(args.mfa_code)
        else:
            print("Error: user_param is required for login action.")
            exit(1)

@Two20Two21
Copy link

Two20Two21 commented Dec 21, 2024

Latest robin-stocks code? I used the code below with the latest release plus the authentication.py module from two weeks ago with the sheriff module and it no longer works for me. It doesn't prompt me for the MFA code, it just errors out.

import robin_stocks.robinhood
import pyotp
from datetime import *

now = datetime.now()
totp = pyotp.TOTP("KACUJH6EKZZCVZ6K").now()
print("TOTP: " + str(totp))
login = robin_stocks.robinhood.login(my_user_name, my_password, mfa_code=totp, store_session=True)

@nat2k5us
Copy link
Author

nat2k5us commented Dec 22, 2024

have you set up an authenticator app?
then you get the 6-digit code from there

[!NOTE]

  • there is no cmd/cli prompt for me either.
  • the totp did not work either

In your login enter the MFA code

    login = r.login(username, password, mfa_code=mfa_code_from_authenticator_of_robinhood)

This will store a .pickle - which will not ask for code for 1 day

@regholl2023
Copy link

I guess I'm just dumb because i have been trying for two days wit this script and no success,import os
import pyotp
import argparse
import robin_stocks.robinhood as r

def generate_token():
totp = pyotp.TOTP("My2factorAppHere").now()
print(f"TOTP: {totp}")

def login(mfa_code):
username = os.getenv("RH_USERNAME")
password = os.getenv("RH_PASSWORD")
if not username or not password:
print("Error: RH_USERNAME or RH_PASSWORD environment variables are not set.")
exit(1)
# Add your login logic here
print(f"User parameter: {mfa_code}")
login = r.login(username, password, mfa_code=mfa_code)
print(f"Login: {login}")

if name == "main":
parser = argparse.ArgumentParser(description="Process command line arguments.")
parser.add_argument("action", choices=["token", "login"], help="Action to perform: 'token' or 'login'")
parser.add_argument("mfa_code", nargs='?', help="User parameter for login action")
args = parser.parse_args()

if args.action == "token":
    generate_token()
elif args.action == "login":
    if args.mfa_code:
        login(args.mfa_code)
    else:
        print("Error: user_param is required for login action.")
        exit(1)

@Two20Two21
Copy link

Two20Two21 commented Dec 22, 2024

@nat2k5us , thanks for responding. Yes, I am passing the mfa code (see my updated code above). If you look at the attachment, that is where everything goes wrong in authentication.py. Right below the blue line in the attached file is: if 'mfa_required' in data:
The code is expecting 'mfa_required' in data but nothing is in data except verification_workflow (also shown in the attachment). As a result, it doesn't prompt for the MFA code. I tried changing that if statement to if True so I could input the MFA code. It tells me wrong MFA code, probably because it is not expecting one.

This broke for me two weeks ago. I loaded the new authentication.py file with the sheriff module and that fixed it. Now it's broken again.

Login Error

@nat2k5us
Copy link
Author

nat2k5us commented Dec 22, 2024

Can you try it on this repo - I will try and backup my pickle file and try again to login as well

also, the the msft authenticator app is what I am using - I remove the old Robinhood and re-added it again with a new code
https://github.com/nat2k5us/rh_login

run the

./run-login-test.sh

@nat2k5us
Copy link
Author

nat2k5us commented Dec 22, 2024

It worked (in the repo I shared) after I deleted the .pickle.robinhood and tried the login again

 - Firstly ensure your correct username and password are present in the env
 - make sure you give enough time for the mfa_code
./run-login-test.sh login mfa_code_from_authenticator_app

After that you can use
./run-login-test.sh login totp

@Dadudekc
Copy link

  1. Invalid Client ID
    The client ID you're using seems outdated. Robinhood occasionally rotates client IDs. The one that’s been working recently is:
    "c82SH0WZOsabOXGP2sxqcj34FxkvfnWRZBKlBjFS"

  2. MFA with Authenticator App
    If you're using an authenticator app for 2FA, you'll need to explicitly handle the TOTP code during login. This ensures your mfa_code gets sent correctly.

  3. Environment Variables for Credentials
    To keep things secure, make sure your RH_USERNAME, RH_PASSWORD, and RH_2FA_SECRET (TOTP secret) are stored as environment variables.

Here’s a code snippet that fixes the issues and works with MFA + the updated client ID:

import os
import requests
import pyotp

def login_robinhood():
    """
    Logs into Robinhood using TOTP-based 2FA.
    Make sure RH_USERNAME, RH_PASSWORD, and RH_2FA_SECRET are set as environment variables.
    """
    # Get credentials from environment variables
    username = os.getenv("RH_USERNAME")
    password = os.getenv("RH_PASSWORD")
    totp_secret = os.getenv("RH_2FA_SECRET")  # Your authenticator app's secret

    if not username or not password or not totp_secret:
        print("Error: Missing RH_USERNAME, RH_PASSWORD, or RH_2FA_SECRET environment variable.")
        return None

    # Generate the TOTP code
    totp = pyotp.TOTP(totp_secret).now()
    print(f"Generated TOTP: {totp}")

    # API endpoint and payload
    url = "https://api.robinhood.com/oauth2/token/"
    payload = {
        "username": username,
        "password": password,
        "mfa_code": totp,
        "grant_type": "password",
        "scope": "internal",
        "client_id": "c82SH0WZOsabOXGP2sxqcj34FxkvfnWRZBKlBjFS",  # Latest client ID
    }

    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    }

    try:
        response = requests.post(url, data=payload, headers=headers)
        response.raise_for_status()
        data = response.json()

        if "access_token" in data:
            print("Login successful!")
            return data
        else:
            print("Login failed. Response:", data)
            return None

    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error: {http_err}")
        if response.text:
            print("Response text:", response.text)
    except Exception as e:
        print(f"An error occurred: {e}")

    return None

if __name__ == "__main__":
    token = login_robinhood()
    if token:
        print("Access Token:", token["access_token"])
    else:
        print("Failed to log in to Robinhood.")

Why This Works:

  • It uses the latest client ID known to work.
  • Handles TOTP generation for MFA using pyotp (make sure your secret is correct).
  • Stores credentials securely using environment variables.
  • Includes error handling for API responses.

Next Steps:

  1. Double-check your environment variables (RH_USERNAME, RH_PASSWORD, RH_2FA_SECRET) are set and correct.
  2. Ensure your TOTP secret is synced with your authenticator app.
  3. Run the script and check for any specific errors in the output.

@regholl2023
Copy link

regholl2023 commented Dec 25, 2024

i got this error back,Traceback (most recent call last):
File "e:\robin_stocks\examples\robinhood examples\two_factor_log_in.py", line 27, in
login = r.login(os.environ['RH_USERNAME'],
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\robin_stocks\venv\Lib\site-packages\robin_stocks\robinhood\authentication.py", line 190, in login
_validate_sherrif_id(device_token=device_token, workflow_id=workflow_id, mfa_code=mfa_code)
File "E:\robin_stocks\venv\Lib\site-packages\robin_stocks\robinhood\authentication.py", line 230, in _validate_sherrif_id
if challenge_response["status"] == "validated":
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
KeyError: 'status', not that i had it working

@regholl2023
Copy link

now i'm getting back this error, HTTP error: 400 Client Error: Bad Request for url: https://api.robinhood.com/oauth2/token/
Response text: {"detail":"This version of Robinhood is no longer supported. Please update your app or use Robinhood for Web to log in to your account."}
Failed to log in to Robinhood.

@nciocchini3
Copy link

nciocchini3 commented Jan 3, 2025

@nat2k5us , thanks for responding. Yes, I am passing the mfa code (see my updated code above). If you look at the attachment, that is where everything goes wrong in authentication.py. Right below the blue line in the attached file is: if 'mfa_required' in data: The code is expecting 'mfa_required' in data but nothing is in data except verification_workflow (also shown in the attachment). As a result, it doesn't prompt for the MFA code. I tried changing that if statement to if True so I could input the MFA code. It tells me wrong MFA code, probably because it is not expecting one.

This broke for me two weeks ago. I loaded the new authentication.py file with the sheriff module and that fixed it. Now it's broken again.

Login Error

Any success with this? I am experiencing the same problem, I am providing the correct MFA code and updated to latest verison of the repo, still fall into the state 'workflow_status_internal_pending' inside _validate_sherrif_id method ...

*** Edit: ok stupid error on my side: when you update the MSA app key, remember to validate it by going back to RH app and tapping 'Continue' at the bottom of the screen. You'll be prompted the Auth app current code. This step is needed to make sure the app validates the correct setup of your MFA key. It works now for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants