I am trying to access the Strava API which requires OAuth. The OAuth process recommends adding a state parameter to the authorization request and comparing the returned state from the redirect with the added state; if the state are the same, then the OAuth process may proceed. However, in my code, the redirect always returns a different state parameter from the one initially sent, causing me to always return make_response("Potential CSRF Attack", 401). Why is the returned state different from the state I send out, and what should I do to make them the same?
Based on some print statements, I know that the length of the returned state parameter is always the same, the value of client_state is appropriately formatted into authorization_url, and client_state is a string.
Here is the link to the Strava OAuth documentation: https://developers.strava.com/docs/authentication/
from flask import Flask, request, render_template, make_response
import secrets
import base64
import webbrowser
app = Flask(__name__)
client_id = "some_id"
redirect_uri = "some_redirect_uri"
response_type = "code"
approval_prompt = "some_response_type"
client_scope = "some_scope"
@app.route("/")
def index():
if request.query_string.decode("utf-8"):
if "state" in request.args:
if client_state == request.args.get("state"):
# token_exchange(request.args.get("code"))
return render_template("Index.html")
else:
return make_response("Potential CSRF Attack", 401)
else:
return make_response("Bad Request", 400)
else:
return render_template("Index.html")
if __name__ == '__main__':
client_state = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b"=").decode("utf-8")
authorization_url = "https://www.strava.com/oauth/authorize?client_id={}&redirect_uri={}&response_type={}" \
"&approval_prompt={}&scope={}&state={}"\
.format(client_id, redirect_uri, response_type, approval_prompt, client_scope, client_state)
app.run(host='0.0.0.0', ssl_context='adhoc')
webbrowser.open(authorization_url)
Thanks in advance!