jmfernandes / robin_stocks

This is a library to use with Robinhood Financial App. It currently supports trading crypto-currencies, options, and stocks. In addition, it can be used to get real time ticker information, assess the performance of your portfolio, and can also get tax documents, total dividends paid, and more. More info at
http://www.robin-stocks.com
MIT License
1.74k stars 468 forks source link

Exception: Invalid bearer token. #458

Closed doctorcolossus closed 6 months ago

doctorcolossus commented 10 months ago

I had been happily using robin_stocks for a week or so, but suddenly seem to be unable to reauthenticate due to an "Invalid bearer token" exception. There appears to have been a previous issue about this, for which a workaround of setting store_session=False was recommended. However, I had already set that argument to False and am still getting this...

from pyotp import TOTP
from robin_stocks.robinhood import login

totp  = TOTP("****").now()

login(username      = username,
      password      = password,
      mfa_code      = totp,
      store_session = False)
  ...
  File "/usr/lib/python3.11/site-packages/robin_stocks/robinhood/authentication.py", line 190, in login
    raise Exception(data['detail'])
Exception: Invalid bearer token.

I double-checked that I'm still able to log in through the web interface.

The payload for the login request looks like this, with my sensitive details asterisked out: {'client_id': '****', 'expires_in': 86400, 'grant_type': 'password', 'password': '****', 'scope': 'internal', 'username': '****', 'challenge_type': 'sms', 'device_token': '****', 'mfa_code': '****'}

I verified the mfa_code sent against the one generated by oathtool manually, and they are identical. The username and password are also both correct. My code had been working fine to authenticate until just now.

Any ideas what the issue could be?

doctorcolossus commented 10 months ago

Still consistently getting this error.

doctorcolossus commented 10 months ago

I tried without providing the OTP as an argument, and that worked:

from robin_stocks.robinhood import login

login(username="****", password="****")
Please type in the MFA code: ****

{'access_token': '****',
 'expires_in': 851916,
 'token_type': 'Bearer',
 'scope': 'internal',
 'refresh_token': '****',
 'mfa_code': '****',
 'backup_code': None,
 'detail': 'logged in with brand new authentication code.'}

I don't want to have to do this interactively before. The automated way seems to be broken, at least for me. Is no one else experiencing this issue?

doctorcolossus commented 10 months ago

Actually now it's mysteriously back to working for me again with the OTP argument too... I didn't change anything in my code. I only tried authenticating several times using different combinations of the available arguments, and suddenly my original code started working again. No idea what the issue was, but I suspect it was something server-side and that perhaps it is arouses suspicion to provide the OTP in the same request as the username and password, and that it might be better to change the login function to always provide the OTP in a follow-up request. But I am just guessing. Anyway, I guess I'll close this for now.

doctorcolossus commented 10 months ago

Here's a pull request to show what I mean about always providing the OTP in a separate request to avoid the situation I described above. Again, it's just a guess, but I suspect that providing the username, password, and OTP all three together might arouse suspicion and lead to this server-side "error" (i.e. block), since that isn't how authentication works in the web application. I am basing this theory on the fact that authentication started working for me again after not providing the OTP as an argument once, in which case the current code prompts the user after making the first request, then delivers the OTP in a follow-up. My suggestion is to also do that even when the OTP is passed as an argument.

doctorcolossus commented 10 months ago

I have closed the pull request and am reopening this issue, since this issue has now started recurring for me despite the proposed change, disproving my hypothesis. I don't know what the issue could be.

hchaudhary1 commented 9 months ago

How are you refreshing the auth token? Using TOTP?