`OAuth2Request` object does not support list in query params
Describe the bug
[Maybe this behavior is normal] Array-like query params (like ?scope=read&scope=write) are not supported when creating OAuth2Request object.
To Reproduce
A minimal example to reproduce the behavior:
from authlib.oauth2.rfc6749.wrappers import OAuth2Request
req = OAuth2Request("GET", "https://127.0.0.1:8000/?scope=read&scope=write")
print(req.data)
# {'scope': 'write'}
Expected behavior
from authlib.oauth2.rfc6749.wrappers import OAuth2Request
req = OAuth2Request("GET", "https://127.0.0.1:8000/?scope=read&scope=write")
print(req.data)
# {'scope': ['read', 'write']}
Environment:
- OS: Fedora 36
- Python Version:
3.10.7 - Authlib Version:
1.1.0
Additional context
class OAuth2Request(object):
def __init__(self, method, uri, body=None, headers=None):
# ...
self.query = urlparse.urlparse(uri).query
# below is the problem:
# url_decode(self.query) returns a list of tuples (name, value)
# but dict merges tuples that have the same key
self.args = dict(url_decode(self.query))
self.form = self.body or {}
#: dict of query and body params
data = {}
data.update(self.args)
data.update(self.form)
self.data = data
I don't know if OAuth 2.0 supports multiple scope in this way. Can you show me the RFC description?
From what I know, the scope should be using +:
https://127.0.0.1:8000/?scope=read+write
Thank you for your response!
You're right. Actually, there is a kind of mismatch between what OAuth2 wants and what a classical application/x-www-form-urlencoded form with a multiselect widget sends.
From what I know there is no RFC to handle list in query params, so what OAuth2 wants is naturally what you must support. However, I think that being able to support what forms may send can really improve DX without breaking (I think) the library flow.
Would it make sense to internally convert multivalue params to + in the init method?