RFC7009: OAuth 2.0 Token Revocation#
This section contains the generic implementation of RFC7009.
Register Revocation Endpoint#
The revocation endpoint can be easily registered to Flask Integration or Django Integration. But there are missing methods to be implemented:
from authlib.oauth2.rfc7009 import RevocationEndpoint
class MyRevocationEndpoint(RevocationEndpoint):
def query_token(self, token, token_type_hint, client):
q = Token.query.filter_by(client_id=client.client_id)
if token_type_hint == 'access_token':
return q.filter_by(access_token=token).first()
elif token_type_hint == 'refresh_token':
return q.filter_by(refresh_token=token).first()
# without token_type_hint
item = q.filter_by(access_token=token).first()
if item:
return item
return q.filter_by(refresh_token=token).first()
def revoke_token(self, token):
token.revoked = True
db.session.add(token)
db.session.commit()
# register it to authorization server
authorization_server.register_endpoint(MyRevocationEndpoint)
After the registration, you can create a response with:
@app.route('/oauth/revoke', methods=['POST'])
def revoke_token():
return server.create_endpoint_response(MyRevocationEndpoint.ENDPOINT_NAME)
API Reference#
- class authlib.oauth2.rfc7009.RevocationEndpoint(server=None)#
Implementation of revocation endpoint which is described in RFC7009.
- authenticate_token(request, client)#
The client constructs the request by including the following parameters using the “application/x-www-form-urlencoded” format in the HTTP request entity-body:
- token
REQUIRED. The token that the client wants to get revoked.
- token_type_hint
OPTIONAL. A hint about the type of the token submitted for revocation.
- create_endpoint_response(request)#
Validate revocation request and create the response for revocation. For example, a client may request the revocation of a refresh token with the following request:
POST /revoke HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token
- Returns:
(status_code, body, headers)
- query_token(token_string, token_type_hint)#
Get the token from database/storage by the given token string. Developers should implement this method:
def query_token(self, token_string, token_type_hint): if token_type_hint == 'access_token': return Token.query_by_access_token(token_string) if token_type_hint == 'refresh_token': return Token.query_by_refresh_token(token_string) return Token.query_by_access_token(token_string) or Token.query_by_refresh_token(token_string)
- revoke_token(token, request)#
Mark token as revoked. Since token MUST be unique, it would be dangerous to delete it. Consider this situation:
Jane obtained a token XYZ
Jane revoked (deleted) token XYZ
Bob generated a new token XYZ
Jane can use XYZ to access Bob’s resource
It would be secure to mark a token as revoked:
def revoke_token(self, token, request): hint = request.form.get("token_type_hint") if hint == "access_token": token.access_token_revoked = True else: token.access_token_revoked = True token.refresh_token_revoked = True token.save()
- CLIENT_AUTH_METHODS = ['client_secret_basic']#
Allowed client authenticate methods
- SUPPORTED_TOKEN_TYPES = ('access_token', 'refresh_token')#
Supported token types
- authenticate_endpoint_client(request)#
Authenticate client for endpoint with
CLIENT_AUTH_METHODS.
- create_endpoint_request(request)#
Convert framework request to OAuth2Request.
- create_response(validated_request: EndpointRequest) tuple[int, Any, list] | None#
Create the HTTP response from a validated request.
- Parameters:
validated_request – The validated EndpointRequest
- Returns:
Tuple of (status_code, body, headers), or None if the application should provide its own response
- validate_request(request: OAuth2Request) EndpointRequest#
Validate the request and return a validated request object.
- Parameters:
request – The OAuth2Request to validate
- Returns:
EndpointRequest with validated data
- Raises:
OAuth2Error – If validation fails