New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove unnecessary get_token_info
#3514
Comments
@sarayourfriend can you please assign this to me? |
@sarayourfriend I was making changes to the application. To replace the function calls to if request.auth:
if not "application" in str(request.auth) or not request.auth.application:
return None
client_id, _, verified = (request.auth.application.client_id,request.auth.application.rate_limit_model , request.auth.application.verified)
if client_id and verified:
return None All the auth test cases passed however there were certain assertion failures during testing : And the checks that were failed due to this code were all because of this assertion error |
@sarayourfriend WHat if instead of removing the for eg: def get_token_info(token: str):
"""
Recover an OAuth2 application client ID and rate limit model from an access token.
:param token: An OAuth2 access token.
:return: If the token is valid, return the client ID associated with the
token, rate limit model, and email verification status as a tuple; else
return ``(None, None, None)``.
"""
logger = parent_logger.getChild("get_token_info")
CHECK FOR WHETHER THE request.auth.application HAS (client_id, tare_limit_model, verified) TUPLE IF YES return (...request.auth.application.<whatever>)
try:
token = AccessToken.objects.get(token=token)
except AccessToken.DoesNotExist:
return _no_result
try:
application = models.ThrottledApplication.objects.get(accesstoken=token) |
The 429 response is a rate limited response, so I don't think it has to do with the change you've made to remove I understand the change to |
Current Situation
get_token_info
entirely duplicates the functionality of the Oauth2 provider backend we use. All the information fromTokenInfo
is available from an authenticated request by way of DRF's implementation.The Oauth2 provider sets
auth
(by way of settingaccess_token
) on the DRF request object to theaccess_token
object, which already hasapplication
anduser
populated. The validator also callsaccess_token.is_valid
which already checks the token expiry and does not populaterequest.auth
if it is expired. Every aspect ofget_token_info
is an unnecessary duplication of what is already happening in the oauth request authentication.DRF sets
auth
based onaccess_token
here: https://github.com/encode/django-rest-framework/blob/0f39e0124d358b0098261f070175fa8e0359b739/rest_framework/request.py#L391request.auth.application
contains all the information that theTokenInfo
objectget_token_info
returns has (and more!).Most routes use the default throttle classes (only thumbnails and a select few others have special throttles, everything else including all search endpoints use the default throttle classes).
There are 7 default throttle classes that run on these requests: burst and sustained for each anon, standard oauth and enhanced oauth (6), in addition to the exempt oauth throttle. Each of these call
get_auth_token
(through the base class'shas_valid_token
method). Each call toget_auth_token
causes up to two database queries but at minimum one. Each of these queries will be identical each time a throttle callsget_auth_token
for a given request. That is, the response will be exactly the same. Replacing these usages withrequest.auth.<whatever>
instead of using the token info object fromget_auth_token
will remove at least 7 unnecessary additional database queries to every single search request (wow!).Suggested Improvement
Remove
get_token_info
and replace all usages of it withrequest.auth
.request.auth
will be an instance ofAccessToken
withapplication
populated with theThrottledApplication
and theUser
instance for the token. Replace calls totoken_info.<whatever>
withrequest.auth.<whatever>
. Ifrequest.auth
is None, then either no token existed on the request or it was invalid. Nothing else needs to be checked.We can also replace checks in serializers
request.user
andrequest.user.is_anonymous
with justrequest.auth is not None
, which should simplify the understanding of authentication in those code paths.Benefit
Remove a significant number of unnecessary queries in the throttle classes that happen on almost every single request.
Also we get to delete code, yay!
The text was updated successfully, but these errors were encountered: