requests / requests-oauthlib

OAuthlib support for Python-Requests!
https://requests-oauthlib.readthedocs.org/
ISC License
1.71k stars 422 forks source link

OAuth 2 web application flow not support PKCE?? #552

Closed Xavierhahaha closed 1 month ago

Xavierhahaha commented 1 month ago

Hi,

I am follow https://requests-oauthlib.readthedocs.io/en/latest/examples/real_world_example.html.

Code:

from flask import Flask, redirect, request, url_for,g,session
from requests_oauthlib import OAuth2Session
import os
import ssl
import logging

ssl._create_default_https_context = ssl._create_unverified_context()
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
app = Flask(__name__)

client_id = 'EPPM_TEST_OAUTH'
client_secret = ''
authorization_base_url = 'https://xxx.com/oauth2/authorize'
token_url = 'https://xxx.com/oauth2/token'

redirect_uri = 'http://127.0.0.1:5000/callback'

def create_oauth_session(client_id:None,pkce:None,redirect_uri:None,token=None, state=None, token_updater=None):

    oauth = OAuth2Session(
        client_id,
        token=token,
        scope=None,
        pkce = pkce,
        redirect_uri=redirect_uri,
        token_updater=token_updater
    )
    return oauth

@app.before_request
def before_request():
    g.token_url='https://xxx.com/oauth2/token'

@app.route('/login')
def login():
    oauth = create_oauth_session(client_id,pkce='S256',redirect_uri=redirect_uri)
    authorization_url, state = oauth.authorization_url(authorization_base_url)
    session['oauth_state'] = state
    return redirect(authorization_url)

@app.route('/callback')
def callback():
    oauth = create_oauth_session(client_id,pkce='S256',redirect_uri=redirect_uri,state=session['oauth_state'])
    token = oauth.fetch_token(
        token_url,
        authorization_response=request.url,
        include_client_id=client_id,
        client_secret=client_secret,
        code=request.args['code'],
        verify=False
    )
    print('token is:"{token}"')
    # token_updater(token)

    return "Authenticated! You can now access protected resources."

@app.route('/protected_resource')
def protected_resource():
    oauth = create_oauth_session(token='your_saved_token')
    response = oauth.get('https://example.com/api/protected_resource')
    return response.json()

if __name__ == '__main__':
    app.secret_key = 'eppm_test_oauth'
    app.run(debug=True)

There will be an dump in def callback(): AttributeError: 'OAuth2Session' object has no attribute '_code_verifier'.

Seems code verifier only created in oauth.authorization_url(authorization_base_url).

Regards,