A JSON Web Token Component for API Star
Project description
apistar-jwt
JSON Web Token Component for use with API Star >= 0.4.
Installation
$ pip install apistar-jwt
Alternatively, install through pipenv.
$ pipenv install apistar-jwt
Usage
Register the JWT
Component with your APIStar app.
from apistar import App
from apistar_jwt.token import JWT
routes = [
# ...
]
components = [
JWT({
'JWT_SECRET': 'BZz4bHXYQD?g9YN2UksRn7*r3P(eo]P,Rt8NCWKs6VP34qmTL#8f&ruD^TtG',
}),
]
app = App(routes=routes, components=components)
Inject the JWT
component in your login function and use it to encode the JWT.
from apistar import exceptions, types, validators
from apistar_jwt.token import JWT
class UserData(types.Type):
email = validators.String()
password = validators.String()
def login(data: UserData, jwt: JWT) -> dict:
# do some check with your database here to see if the user is authenticated
user = db_login(data)
if not user:
raise exceptions.Forbidden('Incorrect username or password.')
payload = {
'id': user.id,
'username': user.email,
'random_data': '102310',
}
token = jwt.encode(payload)
if token is None:
# encoding failed, handle error
raise exceptions.BadRequest()
return {'token': token}
Inject the JWTUser
component in any resource where you want authentication with the provided JWT.
from apistar_jwt.token import JWTUser
def welcome(user: JWTUser) -> dict:
message = f'Welcome {user.username}#{user.id}, here is your random data: {user.token["random_data"]}'
return {'message': message}
Note
Requests made with JWT 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-auth
Decorators
We provide two decorators for convenience to enforce authentication required or allow anonymous users for a route:
from apistar_jwt.token import JWTUser
from apistar_jwt.decorators import anonymous_allowed, authentication_required
@authentication_required
def auth_required(request: http.Request, user: JWTUser):
return user.__dict__
@anonymous_allowed
def anon_allowed(request: http.Request, user: JWTUser):
if user:
return user.__dict__
return None
The @authentication_required
decorator will enforce the user to be logged in for that route. Meanwhile the @anonymous_allowed
will set user: JWTUser=None
and allow anonymous users to hit the route. The default behavior is @authentication_required
so you do not need to annotate with this decorator, it is just to help your code be explicit.
Settings
There are two settings this package uses to identify the username
and user_id
keys in the JWT payload, they are by default:
{
'JWT_USER_ID': 'id',
'JWT_USER_NAME': 'username',
}
If your JWT uses some other kind of key, override these keys when you instantiate your component:
from apistar_jwt.token import JWT
components = [
JWT({
'JWT_USER_ID': 'pk',
'JWT_USER_NAME': 'email',
})
]
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.
from apistar_jwt.token import JWT
components = [
JWT({
'JWT_ALGORITHMS': ['HS256', 'RSA512'],
})
]
SECRET
is a long, randomized, secret key that should never be checked into version control.
from apistar_jwt.token import JWT
components = [
JWT({
'JWT_SECRET': 'QXp4Z83.%2F@JBiaPZ8T9YDwoasn[dn)cZ=fE}KqHMJPNka3QyPNq^KnMqL$oCsU9BC?.f9,oF2.2t4oN?[g%iq89(+'
})
]
For all other settings, use JWT_OPTIONS
key which will pass them along to the underlying PyJWT library when decoding.
from apistar_jwt.token import JWT
components = [
JWT({
'JWT_OPTIONS': {
'issuer': 'urn:foo',
'audience': 'urn:bar',
'leeway': 10,
},
})
]
Quick rundown of the options:
audience
is the urn for this applications audience, it must match a value in the aud
key of the payload. Read more about audience claim.
issuer
is the urn of the application that issues the token, it must match a value in the iss
key of the payload. Read more about the issuer claim
leeway
is the number of seconds of margin an expiration time claim in the past will still be valid for.
A fully customized JWT
component would like like the following:
from apistar_jwt.token import JWT
components = [
JWT({
'JWT_ALGORITHMS': ['HS256', 'RSA512'],
'JWT_USER_ID': 'pk',
'JWT_USER_NAME': 'email',
'JWT_SECRET': 'QXp4Z83.%2F@JBiaPZ8T9YDwoasn[dn)cZ=fE}KqHMJPNka3QyPNq^KnMqL$oCsU9BC?.f9,oF2.2t4oN?[g%iq89(+',
'JWT_OPTIONS': {
'issuer': 'urn:foo',
'audience': 'urn:bar',
'leeway': 10,
},
})
]
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.4.2
- Everything is now a top level export as well, e.g.
from apistar_jwt import JWT
(thanks @jgiradet)
0.4.1
- Added decorator support,
@anonymous_allowed
and@authentication_required
- Added back in test suite
- Updated typings and fixed a bug with instantiating
JWT
component
0.4.0 ** BREAKING CHANGE **
Apistar JWT updated to support Apistar >= 0.4. Pin to 0.3.3 for Apistar 0.3.x support
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.4.2.tar.gz
.
File metadata
- Download URL: apistar_jwt-0.4.2.tar.gz
- Upload date:
- Size: 9.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 426f3374a542815ef15de8675564a4b75418fdeb778ce1a8d10385cbd51ea5db |
|
MD5 | 332a4b4829612847c6bfdd08e3a3206a |
|
BLAKE2b-256 | d0fe6021e994204e21c19fa365fd70fa37409152ac9c73e966a501f145036e42 |
Provenance
File details
Details for the file apistar_jwt-0.4.2-py2.py3-none-any.whl
.
File metadata
- Download URL: apistar_jwt-0.4.2-py2.py3-none-any.whl
- Upload date:
- Size: 6.7 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2305b2a024b0e4b832835cd69b9b892cba167a9dd6ead171f7039e5d6cdaca89 |
|
MD5 | b19bab26d8a387d69637008edaccf7b9 |
|
BLAKE2b-256 | 6b723a8e2ad78b5f53769d5a68d033add5cfbe7e923c9516c25772dd5f1c6fed |