Skip to content

Instantly share code, notes, and snippets.

@RockingRolli
Last active November 28, 2019 09:19
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RockingRolli/79ceab04adb72c106cd6 to your computer and use it in GitHub Desktop.
Save RockingRolli/79ceab04adb72c106cd6 to your computer and use it in GitHub Desktop.
DRF token auth with mongoengine
from rest_framework.authentication import TokenAuthentication
from .models import MongoToken
from rest_framework import exceptions
class MongoTokenAuthentication(TokenAuthentication):
model = MongoToken
def authenticate_credentials(self, key):
try:
token = self.model.objects.get(key=key.decode('UTF-8'))
except self.model.DoesNotExist:
raise exceptions.AuthenticationFailed('Invalid token')
if not token.user.is_active:
raise exceptions.AuthenticationFailed('User inactive or deleted')
return (token.user, token)
import binascii
import os
from django.conf import settings
from django.utils.timezone import now
from mongoengine import Document, StringField, ReferenceField
from mongoengine.fields import DateTimeField
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.user')
class MongoToken(Document):
key = StringField(max_length=44)
user = ReferenceField('PortalUser', required=True)
created = DateTimeField()
def __init__(self, *args, **values):
super().__init__(*args, **values)
if not self.key:
self.key = self.generate_key()
def save(self, *args, **kwargs):
if not self.id:
self.created = now()
return super().save(*args, **kwargs)
def generate_key(self):
return binascii.hexlify(os.urandom(22)).decode()
def __unicode__(self):
return self.key
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework import status
from rest_framework.response import Response
from .models import MongoToken
class ObtainMongoAuthToken(ObtainAuthToken):
model = MongoToken
def post(self, request):
serializer = self.serializer_class(data=request.DATA)
if serializer.is_valid():
token, created = self.model.objects.get_or_create(user=serializer.object['user'])
return Response({'token': token.key})
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
obtain_mongo_auth_token = ObtainMongoAuthToken.as_view()
@dharmit
Copy link

dharmit commented Jun 4, 2015

Hi Roland,

Thanks for putting this up.

I am facing error while trying to integrate this in my project. In the urls.py for the app, I make login point to the view you suggested above:

url(r'^login/$', views.ObtainAuthToken.as_view())

However, when I post username and password to /api/login/ it fails with below AttributeError:

'MetaDict' object has no attribute 'concrete_model'
venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py in check_query_object_type, line 1047

Below is the complete traceback:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/api/login/

Django Version: 1.8.2
Python Version: 2.7.9
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django_extensions',
 'rest_framework',
 'mongoengine.django.mongo_auth',
 'rest_framework_mongoengine',
 'rest_framework.authtoken')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware')


Traceback:
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  407.             response = self.handle_exception(exc)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  404.             response = handler(request, *args, **kwargs)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/rest_framework/authtoken/views.py" in post
  19.         token, created = Token.objects.get_or_create(user=user)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/query.py" in get_or_create
  405.             return self.get(**lookup), False
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/query.py" in get
  325.         clone = self.filter(*args, **kwargs)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/query.py" in filter
  679.         return self._filter_or_exclude(False, *args, **kwargs)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/query.py" in _filter_or_exclude
  697.             clone.query.add_q(Q(*args, **kwargs))
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in add_q
  1304.         clause, require_inner = self._add_q(where_part, self.used_aliases)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in _add_q
  1332.                     allow_joins=allow_joins, split_subq=split_subq,
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in build_filter
  1173.             self.check_related_objects(field, value, opts)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in check_related_objects
  1068.                 self.check_query_object_type(value, opts)
File "/home/dharmit/MyC0d3/crud_noise/venv/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in check_query_object_type
  1047.             if not (value._meta.concrete_model == opts.concrete_model

Exception Type: AttributeError at /api/login/
Exception Value: 'MetaDict' object has no attribute 'concrete_model'

It is my first attempt at working with mongoengine. So I might be making some naive mistake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment