nrbnlulu / strawberry-django-auth

Authentication system for django using strawberry
https://nrbnlulu.github.io/strawberry-django-auth/
MIT License
60 stars 28 forks source link

Enhance Security with HTTPOnly Cookie-Based JWT Authentication Support #508

Open JavierPiedra opened 5 months ago

JavierPiedra commented 5 months ago

Prerequisites

Description

I was wondering if per cookie authentication will be developed, similar to how django-graphql-jwt handles it as described here

Expected behavior

Secure Authentication Mechanism: Upon successful authentication, the server issues a JWT that is securely stored in an HTTPOnly cookie, minimizing the risk of client-side JavaScript access and potential XSS attacks.

Automatic Handling of Tokens: For each subsequent request to the server, the browser automatically includes the JWT stored in the cookie, streamlining the authentication process without manual intervention for token management on the client side.

Enhanced Security Configurations: The JWT cookie is configured with Secure and SameSite attributes, ensuring that the token is only sent over HTTPS connections and providing additional protection against CSRF attacks.

Simplified Client-Side Logic: The client application does not need to manage the storage or transmission of authentication tokens, reducing complexity and potential security vulnerabilities in the client-side code.

Cross-Site Request Forgery (CSRF) Protection: The application includes CSRF protection mechanisms that work in conjunction with the cookie-based authentication to safeguard against unauthorized actions on behalf of authenticated users.

Actual behavior

Token is being sent as accesible to browser and JS

Requirements

asgiref 3.8.1 ASGI specs, helper code, and adapters autopep8 2.1.0 A tool that automatically formats Python code to conform to t... click 8.1.7 Composable command line interface toolkit dj-database-url 2.1.0 Use Database URLs in your Django Application. django 5.0 A high-level Python web framework that encourages rapid devel... django-stubs 4.2.7 Mypy stubs for Django django-stubs-ext 4.2.7 Monkey-patching and extensions for django-stubs graphql-core 3.2.3 GraphQL implementation for Python, a port of GraphQL.js, the ... h11 0.14.0 A pure-Python, bring-your-own-I/O implementation of HTTP/1.1 mypy 1.7.1 Optional static typing for Python mypy-extensions 1.0.0 Type system extensions for programs checked with the mypy typ... psycopg2-binary 2.9.9 psycopg2 - Python-PostgreSQL Database Adapter pycodestyle 2.11.1 Python style guide checker pyjwt 2.8.0 JSON Web Token implementation in Python python-dateutil 2.9.0.post0 Extensions to the standard Python datetime module python-decouple 3.8 Strict separation of settings from code. ruff 0.3.5 An extremely fast Python linter and code formatter, written i... six 1.16.0 Python 2 and 3 compatibility utilities sqlparse 0.4.4 A non-validating SQL parser. strawberry-django-auth 0.376.6 Graphql authentication system with Strawberry for Django. strawberry-graphql 0.224.1 A library for creating GraphQL APIs strawberry-graphql-django 0.37.0 Strawberry GraphQL Django extension types-pytz 2024.1.0.20240203 Typing stubs for pytz types-pyyaml 6.0.12.20240311 Typing stubs for PyYAML typing-extensions 4.10.0 Backported and Experimental Type Hints for Python 3.8+ uvicorn 0.29.0 The lightning-fast ASGI server.

nrbnlulu commented 5 months ago

Hey could you elaborate on the use case of this? since you would be required to save the refresh token in JS anyways am I wrong? Also why wouldn't you just use a session token?

See also #231

advl commented 2 months ago

@nrbnlulu, first thing thanks a lot for this library and all the maintenance work you are doing.

I agree with @JavierPiedra, this would be a worthy feature to have.

You are not required to store any of the tokens in JS.

Currently, using a graphene back-end and a relay front, I store only the tokens expiration (not their content) in LocalStorage (both access and refresh), and if the tokens are expired I ask the server to refresh them before proceeding to the actual call. The tokens themselves are stored as HTTP_ONLY cookies.

How do I make sure the tokens are sent to the server on each call without having read access to them ? I simply use credentials: "include" in my fetch function, as defined here.

This feature would implement a security best practice, in particular against XSS attacks. It would make a difference if you considered it !

(Note : I am currently preparing a switch to strawberry and assessing feature-parity - hence finding myself looking for this in your library.)

nrbnlulu commented 2 months ago

I see.
I currently don't have much time working on new stuff though Ill accept a PR.

advl commented 2 months ago

Thank you @nrbnlulu Will do the pr

guideprojects commented 1 month ago

@advl I've done this in a project I'm developing now. I used SchemaExtension from strawberry.extensions to access the httponly cookies at both ends of the request and modded gqlauth's ArgMixin to run an auth check and to create or delete cookies depending on the result. LMK if you want to see it. I plan to circle back to it in a couple weeks. It works, but I still have a couple issues to clean up.