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
Add support for users with long passwords and 2FA enabled #1496
Comments
That would require giving the 2FA secret to PRAW, and it's only available once. I mean it would just be easier to use a refresh token. Maybe a better method would be to just ask for the 2fa token itself, so that instead of appending it to the password, you give it as a separate parameter. Using the secret will also require another dependency, so I'm not too fond of the idea. |
Thanks for the investigation, @MaybeNetwork! I think that PRAW and prawcore should certainly use this |
I think a better idea may be to include a note on how a user could generate it on their own. Maybe if the |
Of course, all of this depends on prawcore being updated. |
With the linked changes on my forks of praw and prawcore, and assuming that pyotp is on your system. you can run something like
The other usual flows should work too. It's understandable if you don't want to add things that require extra dependencies, since a user with 2FA could just use refresh tokens. Adding a line in the documentation about the Reddit 2FA login bug would also work. |
I think it would just be easier to use the OTP parameter to add a 1-time token. We could mention using pyotp in order to generate this token. |
Another option is to supply a function that will return the 2FA code, so that once could supply |
I think you're onto something. This could be an elegant solution. Usage would look like:
That makes it easier for users without requiring PRAW to add another dependency for an edge case. |
I can adapt the code he has to just take this function. |
There is a missing closing
should be
It could be added if that page is updated with instructions about 2FA. |
Thanks for noting! |
I really like that idea. I'd suggest starting with said callback in prawcore to ensure it works. |
This issue is stale because it has been open for 20 days with no activity. Remove the Stale label or comment or this will be closed in 10 days. |
I can close this issue with a PR soon. |
This issue is stale because it has been open for 20 days with no activity. Remove the Stale label or comment or this will be closed in 10 days. |
This issue is stale because it has been open for 20 days with no activity. Remove the Stale label or comment or this will be closed in 10 days. |
Commenting just so that this can be closed with a link instead of being auto-closed |
This issue is stale because it has been open for 20 days with no activity. Remove the Stale label or comment or this will be closed in 10 days. |
This issue is stale because it has been open for 20 days with no activity. Remove the Stale label or comment or this will be closed in 10 days. |
This issue was closed because it has been stale for 10 days with no activity. |
What did you mean by that? |
He means linking this issue to a PR with |
This issue is stale because it has been open for 20 days with no activity. Remove the Stale label or comment or this will be closed in 10 days. |
This issue was closed because it has been stale for 10 days with no activity. |
Describe the solution you'd like
Reddit's suggested solution of passing the 2FA token to /api/v1/access_token as part of the value of the password parameter, i.e
'password' = password+':'+token
, doesn't work for users with long passwords because of what appears to be a bug on their end. This isn't a big deal, because instead of using Reddit's suggested method, it also turns out that you can pass the 2FA token to /api/v1/access_token in a separateotp
parameter—see below. PRAW or prawcore could be tweaked to handle 2FA tokens if users input their original otp secret at initialization,Describe alternatives you've considered
Update documentation to inform users with long passwords and 2FA enabled that they're SOL.
Additional context
Someone on /r/redditdev claimed that you couldn't use a password flow with 2FA if the password was >= 72 characters long, and it's true. Setting the password to
password:token
fails for large passwords, with or without PRAW. Reddit passwords can be up to 500kb long, but bcrypt only cares about the first 72 characters, so I would guess that Reddit has a bug somewhere in their password validation process.I used the network inspector while logging into new Reddit, and noticed that the password form had a field for the 2FA token named 'otp'. On a whim, I added 'otp':'xxxxxx' to the POST data of the usual non-PRAW oauth login with Python:
...and it worked.
response.json()
returns the usual set of{'access_token': 'xxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx', 'token_type': 'bearer', 'expires_in': 3600, 'scope': '*'}
.So sure enough, 'otp' is a valid parameter for /api/v1/access_token when using a password with 2FA. If a user passed in the otp_secret at initialization, when it comes time to fetch or refresh bearer tokens, PRAW could then just calculate the 2FA token with
pyotp.TOTP(otp_secret).now()
(or with an equivalent function) and add that to the rest of the data in the request.The text was updated successfully, but these errors were encountered: