JWT Locations
JWT can be provided with request in different locations. FastJWT allows to control and configure the JWT locations via the JWT_TOKEN_LOCATION
setting.
Headers
JWT via headers is controlled by two settings:
JWT_HEADER_NAME
: The header name. By default'Authorization'
JWT_HEADER_TYPE
: The header value type/prefix. By default'Bearer'
The FastJWT instance will check this specific header whenever it needs to retrieve a token if the "headers"
location is in JWT_TOKEN_LOCATION
Authentication is only based on the presence of the JWT_HEADER_NAME
header in the headers. To log out your user, remove the authorization header.
Query Parameters
JWT via query parameters is controlled by a single setting:
JWT_QUERY_STRING_NAME
: The key used in the query string to identify the token. By default'token'
Warning
It is important to remember that using JWT in query strings is NOT advised. Even with HTTPS protocol, the request URL is not protected, hence the token is visible. Such request will be saved in plain text in browsers and could be easily compromised.
Specific cases may be of use, for example in case of one time tokens for email validation...
To use JWT in query strings you just need to suffix your URL with ?token=$TOKEN
JSON Body
JWT via JSON Body is controlled by the following parameters:
JWT_JSON_KEY
: The json key relative to the access token. By defaultaccess_token
JWT_REFRESH_JSON_KEY
: The json key relative to the refresh token. By defaultrefresh_token
Please note that sending JWT via JSON Body cannot be accomplished with GET requests, and require the Content-Type: application/json
header.
Cookies
JWT via Cookies is controlled by the following parameters:
JWT_ACCESS_COOKIE_NAME
: Cookie name containing the access token. By defaultaccess_token_cookie
JWT_ACCESS_COOKIE_PATH
: Path of the access token cookie. By default/
JWT_COOKIE_CSRF_PROTECT
: Enable CSRF protection for cookie authentication. By defaultTrue
JWT_COOKIE_DOMAIN
: The domain for cookies set by FastJWT. By defaultNone
JWT_COOKIE_MAX_AGE
: Max age for cookies set by FastJWT. By defaultNone
JWT_COOKIE_SAMESITE
: The SameSite property for cookies set by FastJWT. By defaultLax
JWT_COOKIE_SECURE
: Enable Cookie Secure property. By defaultTrue
JWT_REFRESH_COOKIE_NAME
: Cookie name containing the refresh token. By defaultrefresh_token_cookie
JWT_REFRESH_COOKIE_PATH
: Path of the refresh token cookie. By default/
JWT_ACCESS_CSRF_COOKIE_NAME
: Cookie name containing the access CSRF token. By defaultcsrf_access_token
JWT_ACCESS_CSRF_COOKIE_PATH
: Path of the access CSRF token cookie. By default/
JWT_CSRF_IN_COOKIES
: Add CSRF tokens when cookies are set by FastJWT. By defaultTrue
JWT_REFRESH_CSRF_COOKIE_NAME
: Cookie name containing the refresh CSRF token. By defaultcsrf_refresh_cookie
JWT_REFRESH_CSRF_COOKIE_PATH
: Path of the refresf CSRF token cookie. By default/
If you develop an API to be consumed by a front end application (on web browser). Cookies are an efficient way to provide authentication.
Note on HTTP Only
access
& refresh
tokens set in cookies are HTTP Only
. Meaning they cannot be accessed by JavaScript on client side. This property of [access|refresh]
token cookies is hard coded and is not configurable. This is the expected behavior for authentication through Cookies to avoid XSS (Cross Site Scripting) attacks.
Note on Secure
Secure
cookie property requires an HTTPS request to send the secure cookie. The JWT_COOKIE_SECURE
parameter should always be True
in production. It is set as a configurable parameter for ease of development.
While JWTs in cookies are suitable for web application authentication, they require additional work to prevent attacks. One of the most common attack on cookies is Cross Site Request Forgery (CSRF).
To prevent such CSRF attacks, FastJWT provides double submit CSRF token when setting cookies. The idea is to add a second layer of validation. The CSRF prevention workflow can be summarized as followed:
- Login
- When you log in into your account, the server adds a
Set-Cookie
header for youraccess
token. This cookie isSecure
andHTTP Only
, meaning it cannot be read by JavaScript. This token is the base64 encoded JWT signed with your secrets and contains acsrf
claim with a UUID. - Besides the access token, the server adds another
Set-Cookie
header for the CSRF token. This CSRF cookie does not have theHTTP Only
property and can be read by client-side JavaScript.
- When you log in into your account, the server adds a
- Client-Side request
- When a request is made by the client-side, the request headers should include the CSRF double dubmit token.
If not, the server will invalidate the request and produce a
CSRFError
. If the CSRF token provided does not match the JWTcsrf
claim, the server will invalidate the request.
- When a request is made by the client-side, the request headers should include the CSRF double dubmit token.
If not, the server will invalidate the request and produce a
This workflow prevents CSRF attacks because you need to pass explicitly the CSRF token in your request headers (which is not a default behavior) and JavaScript from another domain will not have read access to this CSRF cookie.
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function getCSRFCookie() {
return getCookie("csrf_access_token")
}
async function requestProtectedRoute(){
const response = await fetch("http://0.0.0.0:8000/protected", {
method: "POST",
credentials: 'include'
headers: {
"X-CSRF-TOKEN": getCSRFCookie()
},
})
return response
}