question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add support for users with long passwords and 2FA enabled

See original GitHub issue

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 separate otp 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:

import pyotp
import requests

otp_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
otp_token = pyotp.TOTP(otp_secret).now()
client_auth = requests.auth.HTTPBasicAuth('client_id','client_secret')
post_data = {
	"grant_type": "password",
	"username": username,
	"password": password,
	"otp": otp_token
}
headers = {"User-Agent": "xxxxxxxxxxxxxxxxxxxxxxxx"}
response = requests.post(
	"https://www.reddit.com/api/v1/access_token",
	auth=client_auth,
	data=post_data,
	headers=headers
)

…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.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:24 (16 by maintainers)

github_iconTop GitHub Comments

2reactions
MaybeNetworkcommented, May 7, 2020

There is a missing closing ) in the documentation about authentication.

print(reddit.auth.url(["identity"], "...", implicit=True)

should be

print(reddit.auth.url(["identity"], "...", implicit=True))

It could be added if that page is updated with instructions about 2FA.

2reactions
jarhill0commented, May 7, 2020

Another option is to supply a function that will return the 2FA code, so that once could supply input and then every hour it would prompt for a code.

I think you’re onto something. This could be an elegant solution. Usage would look like:

import praw
import pyotp 

reddit = praw.Reddit(
    client_id=my_client_id,
    client_secret=my_client_secret,
    user_agent=my_user_agent,
    username='MaybeNetwork',
    password=my_password,
    otp_generator=lambda: pyotp.TOTP(otp_secret).now()
)

That makes it easier for users without requiring PRAW to add another dependency for an edge case.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Multi-factor authentication: How to enable 2FA to step up ...
Want to avoid having your online accounts hacked? Enable two-factor authentication, a crucial security measure that requires an extra step ...
Read more >
Multi-Factor Authentication: Who Has It and How to Set It Up
On macOS go to > System Preferences > iCloud, sign in, click Account Details > Security > Turn on Two-Factor Authentication. (Here are...
Read more >
Two-factor authentication for Apple ID
On your iPhone, iPad, or iPod touch: Go to Settings > your name > Password & Security. Tap Turn On Two-Factor Authentication. Then...
Read more >
Manage app passwords for two-step verification
This support means that after two-step verification is turned on, you'll no longer need app passwords for Office 2013 clients. For more info,...
Read more >
What is Two-Factor Authentication (2FA) and How Does ...
Two-factor authentication adds an extra layer of security to identity and access management programs. Learn about 2FA benefits, use cases and products.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found