JWT graphql (Django + GraphQL (Graphene))
jwt ini digunakan sebagi authentication pengguna, yang mana authentication ini memberikan batasan terhadap akses ases tententu
untuk implementasi jwt ini yang pertama install terlebih dahulu package yang dibutuhkan
🔐 1. Setup Dependencies
pip install graphene-django django-graphql-jwt
⚙️ 2. Configuration in Settings.py
# settings.py
INSTALLED_APPS = [
...
'graphene_django',
'graphql_jwt.refresh_token.apps.RefreshTokenConfig',
]
GRAPHENE = {
'SCHEMA': 'your_app.schema.schema',
'MIDDLEWARE': [
'graphql_jwt.middleware.JSONWebTokenMiddleware',
],
}
AUTHENTICATION_BACKENDS = [
'graphql_jwt.backends.JSONWebTokenBackend',
'django.contrib.auth.backends.ModelBackend',
]
JWT middleware
middleware ini berfunsgi untuk menambahkan user yang login ke resolve. jadi kita bisa mengakses uuser disemua route
from graphql_jwt.middleware import JSONWebTokenMiddleware
from graphql_jwt.decorators import jwt_cookie
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [
path('admin/', admin.site.urls),
path('graphql', jwt_cookie(csrf_exempt(GraphQLView.as_view(
graphiql=True,
middleware=[JSONWebTokenMiddleware], # tambahakn middleware ini
schema=schema,))))
]
🛠️ 3. GraphQL Schema Implementation
# schema.py
import graphene
from graphene_django import DjangoObjectType
from graphql_jwt.decorators import login_required, permission_required
# Protected Query Example
class Query(graphene.ObjectType):
protected_data = graphene.String()
@login_required
@permission_required("blog.view_blog")
def resolve_protected_data(self, info):
return "Secret data!"
# Authentication Mutations
class AuthMutation(graphene.ObjectType):
token_auth = graphql_jwt.ObtainJSONWebToken.Field() # untuk mendapatkan token baru
verify_token = graphql_jwt.Verify.Field() # untuk cek token apakah token valid
refresh_token = graphql_jwt.Refresh.Field() # untuk refresh token apabila expired
delete_token = graphql_jwt.DeleteJSONWebTokenCookie.Field() # untuk delete token / logout
class Mutation(AuthMutation, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query, mutation=Mutation)
🔌 4. URL Configuration
# urls.py
from django.urls import path
from graphene_django.views import GraphQLView
from graphql_jwt.decorators import jwt_cookie
urlpatterns = [
path('graphql/', jwt_cookie(GraphQLView.as_view(graphiql=True))),
]
🔥 5. Client Usage (React/Apollo Example)
a. Login and Get Token
mutation {
tokenAuth(username: "user", password: "pass") {
token
}
}
b. Access Protected Query
// Apollo Client setup
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link-context';
const httpLink = createHttpLink({ uri: '/graphql/' });
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
return {
headers: {
...headers,
authorization: token ? `JWT ${token}` : '',
}
};
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
🛡️ 6. Field-Level Protection (Optional)
class UserType(DjangoObjectType):
class Meta:
model = User
fields = ('username', 'email')
sensitive_data = graphene.String()
@login_required
def resolve_sensitive_data(self, info):
return "For logged-in users only!"
📌 Best Practices
Secure Token Storage
# settings.py
GRAPHQL_JWT = {
'JWT_COOKIE_SECURE': True,
'JWT_COOKIE_HTTPONLY': True,
}
Token Expiration
GRAPHQL_JWT = {
'JWT_EXPIRATION_DELTA': timedelta(hours=1),
'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7),
}
🚨 Error Handling
Example error response:
{
"errors": [
{
"message": "You do not have permission to perform this action",
"extensions": { "code": "UNAUTHENTICATED" }
}
]
}
💡 Production Enhancements
Rate Limiting
from django_graphql_ratelimit import RatelimitMixin
class ProtectedQuery(RatelimitMixin, graphene.ObjectType):
ratelimit_key = "ip"
ratelimit_rate = "10/m"
Audit Logging
def resolve_protected_data(self, info):
log_access(info.context.user)
return sensitive_data
This implementation provides:
- JWT token authentication
- Query/mutation protection via decorators
- Token management (refresh/verify)
- Compatibility with Apollo Client and other GraphQL libraries