A JSON Web Token Component for API Star
Project description
apistar-jwt
JSON Web Token Component for use with API Star. Provides JWTAuthenticate class for JWT Authentication.
WARNING!
This version of apistar-jwt
is only compatible with apistar<0.4
.
Installation
We recommend pipenv for dependency management.
$ pipenv install apistar-jwt
Alternatively, install through pip.
$ pip install apistar-jwt
Usage
To encrypt and decrpyt tokens you must set the include the following setting under your apistar settings.
settings = {
'JWT': {
# do not check your secret into version control!
'SECRET': 'QXp4Z83.%2F@JBiaPZ8T9YDwoasn[dn)cZ=fE}KqHMJPNka3QyPNq^KnMqL$oCsU9BC?.f9,oF2.2t4oN?[g%iq89(+'
}
}
The JWT Component provided can be used as an injected component in a function or through the API Star Authentication Interface. No matter which method you choose to use, the token must be passed as an Authorization
header using the Bearer
scheme in requests made to a resource.
$ curl -i -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoxfQ.fCqeAJGHYwZ9y-hJ3CKUWPiENOM0xtGsMeUWmIq4o8Q" http://localhost:8080/some-resource-requiring-jwt
Authentication
Annotate any routes where you want to use JWT Authentication.
from apistar import annotate
from apistar.interfaces import Auth
from apistar_jwt.authentication import JWTAuthentication
@annotate(authentication=[JWTAuthentication()])
def auth_route(auth: Auth):
# user is authenticated if it reaches here
# get user data
auth.user
# get token
auth.token
# always returns true
auth.is_authenticated()
# get username from either
auth.get_user_id()
auth.get_display_name()
If you need to access the tokens payload you can decrypt the token inside the route.
from apistar import annotate
from apistar.interfaces import Auth
from apistar.types import Settings
from apistar_jwt.authentication import JWTAuthentication
from apistar_jwt.token import JWT
@annotate(authentication=[JWTAuthentication()])
def access_jwt_payload_route(auth: Auth, settings: Settings):
# get payload from token
token = JWT(token=auth.token, settings=settings)
token.payload
Alternatively, we can configure the authentication policy.
from apistar_jwt.authentication import JWTAuthentication
settings = {
'AUTHENTICATION': [JWTAuthentication()]
}
As A Component
Register the JWT Component in your App:
from apistar import Component
from apistar_jwt.authentication import get_jwt
from apistar_jwt.token import JWT
components = [
Component(JWT, init=get_jwt)
]
app = App(
routes=routes,
components=components
)
Add the component to your function definition:
from apistar import http
from apistar_jwt.token import JWT
def echo_jwt_payload(request: http.Request, token: JWT):
return token.payload
Note that you have to do your own authentication check using this method. The payload will be returned as it was encoded and won't respect the JWT
settings for USERNAME
and ID
as they correlate with the Auth
interface which is not utilized when using JWT
as an injected component.
from apistar import http
from apistar import exceptions
from apistar_jwt.token import JWT
def auth_required_endpoint(request: http.Request, token: JWT):
if token.payload is None:
raise exceptions.Forbidden()
username = token.payload.get('username', '')
other_data_you_put_in_payload = token.payload.get('other_data', '')
return {
'username': username,
'other_data': other_data_you_put_in_payload,
}
Settings
There are two settings this package uses to identify the username
and user_id
keys in the JWT payload, they are by default
settings = {
'JWT': {
'USERNAME': 'username',
'ID': 'id',
}
}
If your JWT uses some other kind of key, copy these keys into your settings and set the correct key values.
ID
is not required, but available if you would like to include a different id field in your JWT payload.
Other JWT Settings
ALGORITHMS
is related to the algorithms used for decoding JWTs. By default we only use 'HS256' but JWT supports passing an array of supported algorithms which it will sequentially try when attempting to decode.
settings = {
'JWT': {
'ALGORITHMS': ['HS256', ],
}
}
SECRET
is a long, randomized, secret key that should never be checked into version control.
settings = {
'JWT': {
'SECRET': 'QXp4Z83.%2F@JBiaPZ8T9YDwoasn[dn)cZ=fE}KqHMJPNka3QyPNq^KnMqL$oCsU9BC?.f9,oF2.2t4oN?[g%iq89(+'
}
}
ISSUER
is the urn for which JWT's should be accepted from. Read more about issuer claim.
settings = {
'JWT': {
'ISSUER': 'urn:foo'
}
}
AUDIENCE
is the urn for this applications audience, it must match a value in the aud
key of the payload. Read more about issueer claim.
settings = {
'JWT': {
'AUDIENCE': 'urn:bar'
}
}
LEEWAY
is the number of seconds of margin an expiration time claim in the past will still be valid for.
settings = {
'JWT': {
'LEEWAY': 10
}
}
Encoding JWTs
As a convenience, we provide a simple encode
method to create JWTs, if you need more advanced JWT encodings, please visit the PyJWT docs.
from apistar.types import Settings
from apistar_jwt.token import JWT
def encrypt_payload(request: http.Request, settings: Settings):
SECRET = settings['JWT'].get('SECRET')
payload = {'email': 'test@example.com'}
# algorithm for encoding defaults to HS256
token = JWT.encode(payload, secret=SECRET)
# use the algorithm keyword to pass a specific algorithm
token = JWT.encode(payload, secret=SECRET, algorithm='RS512')
return {'token': token}
You may pass valid claim names or other valid kwargs to JWT.encode()
. These claims help with your JWT's security. The following example demonstrates using all the claims, but they are all optional and the values provided for the claims in the example are arbitrary.
from datetime import datetime, timedelta
from apistar.types import Settings
from apistar_jwt.token import JWT
def encrypt_payload(request: http.Request, settings: Settings):
SECRET = settings['JWT'].get('SECRET')
payload = {
'email': 'test@example.com',
'iss': 'urn:foo', # only accept jwt from this issuer
'aud': ['urn:foo', 'urn:bar', 'urn:baz'] # only these audiences can decrpyt
'iat': datetime.utcnow() # issued at to know time JWT was issued
'exp': datetime.utcnow() + timedelta(seconds=30), # expiration time
'nbf': datetime.utcnow(), # not before time
}
# you may also pass optional kwargs like headers to the encode method
token = JWT.encode(
payload,
secret=SECRET,
algorithm='RS512',
headers={'kid': '230498151c214b788dd97f22b85410a5'},
)
return {'token': token}
Developing
This project uses pipenv
to manage its development environment, and pytest
as its tests runner. To install development dependencies:
pipenv install --dev
To run tests:
pipenv shell
pytest
This project uses Codecov to enforce code coverage on all pull requests. To run tests locally and output a code coverage report, run:
pipenv shell
pytest --cov=apistar_test/
HISTORY
0.3.3
Update dev deps so we are using metadata 2.1 spec for pypi.
0.3.2
Updates to pin dependencies for Apistar 0.3.x and add Markdown rendering to pypi.org
0.3.1
Release for Apistar 0.3.x
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file apistar_jwt-0.3.3.tar.gz
.
File metadata
- Download URL: apistar_jwt-0.3.3.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3a4288701244da28bd78c5f8811ce7ab67d9116e32cf8ef23389c3f07a37aa62 |
|
MD5 | ffe98190948968f215d755474c3ed4a6 |
|
BLAKE2b-256 | 29e98ffb77c8dc107c9e904ce930060d1cd3e41499835c7de956d121820434d3 |
File details
Details for the file apistar_jwt-0.3.3-py2.py3-none-any.whl
.
File metadata
- Download URL: apistar_jwt-0.3.3-py2.py3-none-any.whl
- Upload date:
- Size: 6.5 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d1c1ef655cfba593f79bc86395b41aa5667cb50d15801b399f8f8e4cd8446bed |
|
MD5 | 3ea380b609ff39879cf0b2636b001fd5 |
|
BLAKE2b-256 | 797417800d643fa34f982d85f6ec4411a8356c533d830b638c96736fdfb33360 |