Skip to content

Instantly share code, notes, and snippets.

@kemitche
Last active July 25, 2023 16:12
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save kemitche/9749639 to your computer and use it in GitHub Desktop.
Save kemitche/9749639 to your computer and use it in GitHub Desktop.
reddit OAuth 2.0 Python Webserver Example
#!/usr/bin/env python
from flask import Flask, abort, request
from uuid import uuid4
import requests
import requests.auth
import urllib
CLIENT_ID = None # Fill this in with your client ID
CLIENT_SECRET = None # Fill this in with your client secret
REDIRECT_URI = "http://localhost:65010/reddit_callback"
def user_agent():
'''reddit API clients should each have their own, unique user-agent
Ideally, with contact info included.
e.g.,
return "oauth2-sample-app by /u/%s" % your_reddit_username
'''
raise NotImplementedError()
def base_headers():
return {"User-Agent": user_agent()}
app = Flask(__name__)
@app.route('/')
def homepage():
text = '<a href="%s">Authenticate with reddit</a>'
return text % make_authorization_url()
def make_authorization_url():
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
state = str(uuid4())
save_created_state(state)
params = {"client_id": CLIENT_ID,
"response_type": "code",
"state": state,
"redirect_uri": REDIRECT_URI,
"duration": "temporary",
"scope": "identity"}
url = "https://ssl.reddit.com/api/v1/authorize?" + urllib.urlencode(params)
return url
# Left as an exercise to the reader.
# You may want to store valid states in a database or memcache.
def save_created_state(state):
pass
def is_valid_state(state):
return True
@app.route('/reddit_callback')
def reddit_callback():
error = request.args.get('error', '')
if error:
return "Error: " + error
state = request.args.get('state', '')
if not is_valid_state(state):
# Uh-oh, this request wasn't started by us!
abort(403)
code = request.args.get('code')
access_token = get_token(code)
# Note: In most cases, you'll want to store the access token, in, say,
# a session for use in other parts of your web app.
return "Your reddit username is: %s" % get_username(access_token)
def get_token(code):
client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
post_data = {"grant_type": "authorization_code",
"code": code,
"redirect_uri": REDIRECT_URI}
headers = base_headers()
response = requests.post("https://ssl.reddit.com/api/v1/access_token",
auth=client_auth,
headers=headers,
data=post_data)
token_json = response.json()
return token_json["access_token"]
def get_username(access_token):
headers = base_headers()
headers.update({"Authorization": "bearer " + access_token})
response = requests.get("https://oauth.reddit.com/api/v1/me", headers=headers)
me_json = response.json()
return me_json['name']
if __name__ == '__main__':
app.run(debug=True, port=65010)
@eirsep
Copy link

eirsep commented Apr 6, 2015

I am working on Ubuntu 14.04 distro.
When i try to run the program, I am getting the following error:

  • Running on http://127.0.0.1:65010/ (Press CTRL+C to quit)
  • Restarting with stat
    Traceback (most recent call last):
    File "authorization.py", line 93, in
    app.run(debug=True, port=65010)
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 772, in run
    run_simple(host, port, self, **options)
    File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 622, in run_simple
    reloader_type)
    File "/usr/local/lib/python2.7/dist-packages/werkzeug/_reloader.py", line 269, in run_with_reloader
    reloader.run()
    File "/usr/local/lib/python2.7/dist-packages/werkzeug/_reloader.py", line 159, in run
    for filename in chain(_iter_module_files(), self.extra_files):
    File "/usr/local/lib/python2.7/dist-packages/werkzeug/_reloader.py", line 70, in _iter_module_files
    for package_path in getattr(module, 'path', ()):
    File "/usr/lib/python2.7/dist-packages/six.py", line 116, in getattr
    _module = self._resolve()
    File "/usr/lib/python2.7/dist-packages/six.py", line 105, in _resolve
    return _import_module(self.mod)
    File "/usr/lib/python2.7/dist-packages/six.py", line 76, in _import_module
    import(name)
    ImportError: No module named _winreg

@jackfischer
Copy link

Thank you!!

@riyoua
Copy link

riyoua commented Dec 7, 2016

i tried your code on kali linux and i got this error after i grant authorization to my app :
NotImplementedError

NotImplementedError
Traceback (most recent call last)

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 2000, in __call__

return self.wsgi_app(environ, start_response)

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1991, in wsgi_app

response = self.make_response(self.handle_exception(e))

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1567, in handle_exception

reraise(exc_type, exc_value, tb)

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1988, in wsgi_app

response = self.full_dispatch_request()

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1641, in full_dispatch_request

rv = self.handle_user_exception(e)

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1544, in handle_user_exception

reraise(exc_type, exc_value, tb)

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1639, in full_dispatch_request

rv = self.dispatch_request()

File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1625, in dispatch_request

return self.view_functions[rule.endpoint](**req.view_args)

File "/root/Desktop/newproj/test4.py", line 63, in reddit_callback

access_token = get_token(code)

File "/root/Desktop/newproj/test4.py", line 73, in get_token

headers = base_headers()

File "/root/Desktop/newproj/test4.py", line 21, in base_headers

return {"User-Agent": user_agent()}

File "/root/Desktop/newproj/test4.py", line 18, in user_agent

raise NotImplementedError()

NotImplementedError

The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.

To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object

can you help me please ?

@hoenie-ams
Copy link

I have the same issue as @riyoua

@Bsabz
Copy link

Bsabz commented May 9, 2017

@hoenie-ams @riyoua: You need to actually return your User-Agent in the user_agent function like so,

image

@prashant2796
Copy link

prashant2796 commented Feb 16, 2018

what is user agent and where can i find it ? i am implementing this code for google

@neonoatmeal
Copy link

@prashant2796 A user agent is a description that tells a little bit about what your using such as "MozillaFirefox17.1;Ubuntu16.04;Python3; by: Mynameiskaleb"
From what I can tell, some sites expect them to be in certain formats like Firefox and others aren't too picky as long as it gives a decent description.

@srivatsshankar
Copy link

This is brilliant! This is the first time I have understood what is going on with OAuth! Simple and clear. Thank you!

@AbdulhadeAhmad
Copy link

Thank you very much, this helped me a lot!

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