# Protect your API on Python

### **Extract the Bearer Token from request header**[**​**](https://docs.logto.io/docs/recipes/protect-your-api/python#extract-the-bearer-token-from-request-header)

```
"""requires-auth.py
"""
def get_auth_token():
 auth = request.headers.get("Authorization", None)
 if not auth:
   raise Error({ code: 'auth.authorization_header_missing', status: 401 })
 contents = auth.split()
 if len(contents) < 2
   raise Error({code: 'auth.authorization_token_invalid_format', status: 401})
 elif contents[0] != 'Bearer'
   raise Error({code: 'auth.authorization_token_type_not_supported', status: 401})
 return contents[1]

```

### **Token validation**[**​**](https://docs.logto.io/docs/recipes/protect-your-api/python#token-validation)

For demonstration, we use the Flask app and [jose](https://github.com/mpdavis/python-jose) package to create the require\_auth decorator to validate the token's signature, expiration status, and required claims.

#### **Install jose as your dependency**[**​**](https://docs.logto.io/docs/recipes/protect-your-api/python#install-jose-as-your-dependency)

```
pip install python-jose[rsa]
```

#### **Retrieve Auth’s OIDC configurations**[**​**](https://docs.logto.io/docs/recipes/protect-your-api/node#retrieve-logtos-oidc-configurations)

You will need a JWK public key set and the token issuer to verify the signature and source of the received JWS token. All the public Auth Authorization Configurations can be found at <https://your-auth-domain/.well-known/openid-configuration>.

e.g. Call <https://nightly-accounts-api.complyment.com/.well-known/openid-configuration>. And locate the following two fields in the response body:

```
{
 "jwks_uri": "https://nightly-accounts-api.complyment.com/.well-known/jwks.json",
 "issuer": "https://nightly-accounts-api.complyment.com"
}

```

#### **Create the authorization validation decorator using the Auth’s configurations**[**​**](https://docs.logto.io/docs/recipes/protect-your-api/python#create-the-authorization-validation-decorator-using-the-logtos-configurations)

```
"""requires-auth.py
"""
import json
from flask import request,  _request_ctx_stack
from six.moves.urllib.request import urlopen
from functools import wraps
from jose import jwt
def requires_auth(f):
 @wraps(f)
 def decorated(*args, **kwargs):
   token = get_token_auth_header()
   # jwks_uri endpoint retrieved from Auth
   jwks_uri = urlopen('https://nightly-accounts-api.complyment.com/.well-known/jwks.json')
   # issuer retrieved from Auth
   issuer = 'https://<your-auth-domain>'
   jwks = json.loads(jwks_uri.read())
   try:
     payload = jwt.decode(
       token,
       jwks,
       algorithms='RS256',
       audience='<your request listener resource indicator>',
       issue=issuer
       options={
         'verify_at_hash': False
       }
     )
   except Exception:
     # exception handler
     raise Error({code: 'invalid_token', status: 401})
     # Custom code to process payload
   _request_ctx_stack.top.user_id = payload.get('sub')
   return f(*args, **kwargs)
 return decorated

```

### **Apply decorator to your API**[**​**](https://docs.logto.io/docs/recipes/protect-your-api/python#apply-decorator-to-your-api)

```
from flask import Flask
from flask_cors import cross_origin

APP = Flask(__name__)

@APP.route("/user/info")
@cross_origin(headers=["Content-Type", "Authorization"])
@requires_auth
def api:
 # Your API Logic

```

###


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://authdocs.skill-mine.com/licentio-documentation/protect-your-api/protect-your-api-on-python.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
