> For the complete documentation index, see [llms.txt](https://authdocs.skill-mine.com/licentio-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://authdocs.skill-mine.com/licentio-documentation/protect-your-api/protect-your-api-on-python.md).

# 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

```

###
