Implementing User Authentication #740
Replies: 11 comments 7 replies
-
Hi thanks for taking an interest in So basically you have to create your own Here's how i did it: class Token(models.Model):
token = models.CharField(
default=partial(
get_random_string,
16,
),
unique=True,
max_length=16,
editable=False,
)
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, related_name="user")
def __str__(self) -> str:
return f"User : {self.user.username} | Token : {self.token}"
class Meta:
indexes = [
models.Index(fields=["token"]),
]
verbose_name = _("token")
verbose_name_plural = _("tokens") Now you have to setup token claims.
import logging
from typing import Any
from apps.user.models import CustomUser
from ninja.compatibility import get_headers
from ninja.security import HttpBearer
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.http import HttpRequest
from .models import Token
class AuthBearer(HttpBearer):
def authenticate(
self,
request: HttpRequest,
token: str,
) -> CustomUser | AnonymousUser:
try:
token_data = Token.objects.get(token=token)
return token_data.user
except Token.DoesNotExist:
return AnonymousUser Then when you have a protected route you just add Auth class to it :) from .models import Token
from ninja import Router
from django.http import HttpRequest, HttpResponse
from .auth import AuthBearer
router = Router()
@router.delete("/logout", auth=AuthBearer())
def post_user_logout_info(request: HttpRequest) -> HttpResponse:
token: Token = Token.objects.get(user=request.auth)
token.delete()
return HttpResponse("Successful", status=200) If you need a reference you can see my project : |
Beta Was this translation helpful? Give feedback.
-
Ah! Beautiful! Thanks for this. I will implement this at once. Meanwhile do
you min taking a look at my project and letting me know if I have got
it right, especially the apps/movies... I am not so certain if I have got
the routing done correctly. I tried to do it according to the documentation
but it gave me errors. Had to leave it the way it is now.
https://github.com/KrystianMaccs/cinema
Thanks.
…On Fri, 14 Apr 2023, 02:30 baseplate-admin, ***@***.***> wrote:
Hi thanks for taking an interest in django-ninja,
So basically you have to create your own Token model instance.
Here's how i did it:
class Token(models.Model):
token = models.CharField(
default=partial(
get_random_string,
16,
),
unique=True,
max_length=16,
editable=False,
)
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, related_name="user")
def __str__(self) -> str:
return f"User : {self.user.username} | Token : {self.token}"
class Meta:
indexes = [
models.Index(fields=["token"]),
]
verbose_name = _("token")
verbose_name_plural = _("tokens")
Now you have to setup token claims.
django-ninja provides you with authentication class
<https://django-ninja.rest-framework.com/guides/authentication/>. You
need to override it.
import loggingfrom typing import Any
from apps.user.models import CustomUserfrom ninja.compatibility import get_headersfrom ninja.security import HttpBearer
from django.conf import settingsfrom django.contrib.auth.models import AnonymousUserfrom django.http import HttpRequest
from .models import Token
class AuthBearer(HttpBearer):
def authenticate(
self,
request: HttpRequest,
token: str,
) -> CustomUser | AnonymousUser:
try:
token_data = Token.objects.get(token=token)
return token_data.user
except Token.DoesNotExist:
return AnonymousUser
Then when you have a protected route you just add Auth class to it :)
from .models import Tokenfrom ninja import Router
from django.http import HttpRequest, HttpResponse
from .auth import AuthBearer
router = Router()
@router.delete("/logout", auth=AuthBearer())def post_user_logout_info(request: HttpRequest) -> HttpResponse:
token: Token = Token.objects.get(user=request.auth)
token.delete()
return HttpResponse("Successful", status=200)
If you need a reference you can see my project :
- models.py
<https://github.com/baseplate-admin/CoreProject/blob/e67800c8a38989f668f71d7549dcdd94b6941eb1/backend/django_core/apps/api/models.py>
- auth.py
<https://github.com/baseplate-admin/CoreProject/blob/e67800c8a38989f668f71d7549dcdd94b6941eb1/backend/django_core/apps/api/auth.py>
- endpoints (login,logout,signup)
<https://github.com/baseplate-admin/CoreProject/tree/e67800c8a38989f668f71d7549dcdd94b6941eb1/backend/django_core/apps/api/views/user>
—
Reply to this email directly, view it on GitHub
<#740 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APILC54RKUU7AXUOBV5CCE3XBCSCFANCNFSM6AAAAAAW5ZJ6KI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I am not on the system now. But the error said module couldn't be found.
And this was what I did. I created api file in my movies app and then
another api file in the main project next to the urls file. In the
movies.api file, I used Router() and then in the main project I used
NinjaAPI.
…On Fri, 14 Apr 2023, 03:07 baseplate-admin, ***@***.***> wrote:
Do you have the error stacktrace?
—
Reply to this email directly, view it on GitHub
<#740 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APILC5ZUG7LFMEA2UW5JKK3XBCWMJANCNFSM6AAAAAAW5ZJ6KI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Alright. That would be great. Thank you very much. 😁
…On Fri, 14 Apr 2023, 03:19 baseplate-admin, ***@***.***> wrote:
Ahha. This is probably due to the django handles importing. I can take a
look after 1-2 hour. Currently in work
—
Reply to this email directly, view it on GitHub
<#740 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APILC5ZCYT37TK3KTNKAPBDXBCX37ANCNFSM6AAAAAAW5ZJ6KI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Hi, when I tried to implement your authentication logic, and run server, I
get this error:
ImportError: email-validator is not installed, run `pip install
pydantic[email]`
…On Fri, 14 Apr 2023 at 03:56, baseplate-admin ***@***.***> wrote:
I opened an issue. See if that fixes
—
Reply to this email directly, view it on GitHub
<#740 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APILC57727Z2JZJJN2TEW7TXBC4GLANCNFSM6AAAAAAW5ZJ6KI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Yeah, done. However, I have another question that is unrelated to
django-ninja. I have 2 databases: postgres and mongodb on this django
project. I want to sync both databases such that once a model instance
is created, saved or updated on postgres, it automatically gets saved
on mongodb. How can i do this?
…On Sat, 15 Apr 2023 at 03:12, baseplate-admin ***@***.***> wrote:
pip jnstall it?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
For easy query. It's a project I was asked to do and I just need ideas.
…On Sat, 15 Apr 2023 at 03:19, baseplate-admin ***@***.***> wrote:
I have a counter question. Why do you need mongodb?
—
Reply to this email directly, view it on GitHub
<#740 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APILC5Y5CWVFN7D6OQTI52LXBIAUPANCNFSM6AAAAAAW5ZJ6KI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Yeah, but I gotta link both databases somehow so that when the signal is
fired, the changes take place. I have the signals already, it's just how to
do the linking that eludes me.
…On Sat, 15 Apr 2023 at 03:25, baseplate-admin ***@***.***> wrote:
Setup django signals, so Whenever you save an object it gets created to
mongodb.
—
Reply to this email directly, view it on GitHub
<#740 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APILC53JHWH3ETLMGVBC733XBIBIBANCNFSM6AAAAAAW5ZJ6KI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Okay. Let me go ahead and register the signals.
Thanks for your help
…On Sat, 15 Apr 2023, 03:32 baseplate-admin, ***@***.***> wrote:
Did you register the signal?
The linking is impossible. There's no good package to do it. You can make
your own but i would highly be against it
—
Reply to this email directly, view it on GitHub
<#740 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APILC5Z7WILCR5XCG74DDLTXBICFPANCNFSM6AAAAAAW5ZJ6KI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
@KrystianMaccs if you have an answer please mark an answer. Helps other find this later :) |
Beta Was this translation helpful? Give feedback.
-
Hi Vitaliy, I just got started with django-ninja this week and so far it's been good and I am getting a hang of it. However, I have a little trouble implementing User Authentication and Authorization. How does it work? I have a User model already and schema. What do I do from here? Meanwhile, this is my repo: https://github.com/KrystianMaccs/cinema.git
Beta Was this translation helpful? Give feedback.
All reactions