Django Two Factor Auth combined with Rest Framework? - django

I'm trying to implement django two factor auth into my Rest API. Is there a possibility to implement this by using custom views and model creations? Because, at least that's the way I understood it, this library is mainly working based on default django templates and predefined routes.
Is it possible to combine this library with a Rest API or should I use another library?

You cam use pyotp library. It's compatible with most of the two factor authenticator app like google authenticator. Very easy to use.
Here is an example how to use use:
base32 = pyotp.random_base32()
>>> base32
'ERAAADLXLDFBVL2JSR4RLR73DWFWYSTU'
>>> totp = pyotp.TOTP(base32)
>>> totp.now()
'206328'
It will generate random code after every 30 seconds. For generate provisioning URIs for use with the QR Code scanner:
pyotp.totp.TOTP('ERAAADLXLDFBVL2JSR4RLR73DWFWYSTU').provisioning_uri(name='alice#google.com', issuer_name='Secure App')
>>> 'otpauth://totp/Secure%20App:alice%40google.com?secret=ERAAADLXLDFBVL2JSR4RLR73DWFWYSTU&issuer=Secure%20App'

There is a package for Django REST 2FA:
https://github.com/merixstudio/django-trench

Related

What are the differences between APIView and Django generic views in terms of usage?

I am trying to build a Django backend API that will be accessible both by a mobile app and a website. I am setting up the user authentication functionality using the rest-framework module.
Can anyone explain the difference in functionality and usage between the two types of views (APIView and Django display/editing generic views) and which ones would be more suitable for my goals?
Use viewsets.ModelViewSet when you are going to allow all or most of CRUD operations on a model.
Use generics.* when you only want to allow some operations on a model
Use APIView when you want to completely customize the behaviour.
baed on https://books.agiliq.com/projects/django-api-polls-tutorial/en/latest/more-views-and-viewsets.html

Using Django Rest Framework for only certain apps inside Django Application

I'm not sure if this is possible since an extensive search gave me nothing. Or I might be searching the wrong terms.
Now I have a few apps inside my Django application as follows:
--AppOne
--AppTwo
--ExtendedAdmin
manage.py
Now, AppOne and AppTwo use Django Rest Framework and its related Token Auth Mechanism. For the extendedAdmin, I'd like to use native Django Auth or even SessionAuth of DRF since I'm trying to add quite an extensive admin panel to the application. I've not been able to find a satisfactory way of customizing Django Rest Framework to work it's auth mechanisms only for certain applications. Is there a way to do this? If not, what should I be doing different?
So far, I know you cannot. Because django rest framework intercepts the url and then performs its own logic of token validation. But there are solutions that you can use to keep both Session and Token Authentication.
I am using this for all my projects -
I keep Session Authentication for all urls that will be accessed for normal browsing
and I use api urls with django rest framework to be prefixed with /api for my api urls
For example -
The Session Based login is at http://<host>/account/login
and TokenBased login is at http://<host>/api/account/login
The easiest way to make prefixed url for django rest framework is by using Routers - http://www.django-rest-framework.org/api-guide/routers/#defaultrouter
Example -
class UserViewSet(ModelViewSet): # just a sample view set
...
router = routers.SimpleRouter()
router.register(r'api/users', UserViewSet)

REST app architecture

I am working on a RESTful application, which goal is to allow user to track his results, progress and performance in sport activities.
I want to create two or more clients for this app:
1) web client
2) mobile client ( iOS / Android )
I am writting it in django using tastypie app and I wonder if I should make web client in the same application, which will provide the RESTful api or should I leave it as a pure REST service and build separate web client, which will contact it via the api?
As for now I don't see any drawbacks of making both in one, but I am not an expert in programs with such an architecture, so I am looking for some advise with argumentation behind it.
It is not easy to answer to this as it depends a lot on what kind of service you are building.
Approach 1: Traditional Django app + API
Here your Django-app and the tastpie API share common data models but present them differently. One using Djangos templates and views and the other using tastypie.
Pros:
Building a traditinal web service is relatively easy and well understood problem
Django provides a lot of tools for this
Cons:
There is no gurantee that the API presents the same functionality as the web service
You have to maintain two different ways to interact with your data.
Approach 2: API only + JavaScript webapp that uses the API
There is only one interface to the service via the tastypie API. The web client is built separately using javascript tools like backbone.js and backbone-tastypie.
Pros:
You gurantee that the 3rd party developers can build a service with the same functionality as your web service (see dogfooding).
Works pretty nicely if your service is more of an application than a collection of pages.
Cons:
Client side JavaScript tools are not as good as Djangos (for example, templating).
Client side rendering of templates only happens after most of the resources are loaded.
First pageload is slow
Pre-IE9 browsers won't work without trick, IE9 may need tricks
You really need to mind about browser caches
SEO is not as straightforward as with traditional web service.
Approach 3: API only + call the API from Django views
Pretty much same as Approach 1 but instead of using your models directly you call the tastypie resources internally.
Pros:
You can still use most of the Django tools.
You mostly use the same API as potential 3rd party developers
Cons:
I do not know how much overhead this incurs.
There is a fourth way to do this, which extends on #seppo-erviälä Approach 1 and Approach 2:
Approach 4: API View + Django View via Handler
Create a handler that returns the RESTful resource just as RESTful API view normally would. But this handler is callable from anywhere. It gets the same request dictionary that the view gets and it returns the same JSON the view returns. So now, the architecture is:
Handler
/ | \
/ | \
/ | \
/ | \
RESTfulView | Normal Django View
|
Anything Else
The handler:
class ResourceHandler:
def create_resource(self, data):
# code
def fetch_resource(self, rId):
# code
# and so on
and you call it from the views like so:
# /views/restfulview.py
# using django-rest-framework
from rest_framework.response import Response
class RESTCallView(APIView):
h = ResourceHandler()
def get(self, request, rId):
return Response(self.h.fetch_resource(rId))
# /views/normalview.py
from django.views.generic.base import TemplateView
class SomeDjangoView(TemplateView):
h = ResourceHandler()
def get(self, request, rId):
return HttpResponse(self.h.fetch_resource(rId))
Of course, this is just example code and not really pythonic but you get the idea.
I work in a large e-commerce company and some of my teammates have used this approach to good success.
Some other advantages are:
Migration of old data becomes a lot easier now since you just need to create the dict and send it to the Handler. Similarly, sync also becomes a lot easier.
Changes to APIs are in one place, and you can cut off the app without killing access to the data.
Hope this helps you too.. :)
Better create a pure REST service and consume it from both the client. It will provide a clean layered architecture as you are not mixing service with client in one app. By having a common service separately you would have : Separation of concern, Clean Architecture, Proper Laying, Readability and better Maintainability.

Alternative Django Authenication

Need to integrate Django with an existing authentication system. That system has it's own database, API, login/logout,edit profile web pages and cookie.
(I may have to add a few additional profile fields stored/updated locally)
What's the proper approach to substitute the out-of-the-box authentication in Django?
The proper approach to substitute authentication from django's out-of-the-box to your own is to substitute your classes in the AUTHENTICATION_BACKENDS tuple in settings.py as described in http://docs.djangoproject.com/en/dev/topics/auth/#specifying-authentication-backends. This is incredibly useful for just the issue you're describing.
A good example of an authentication backend done this way is django-cas. This uses CAS to authenticate in a django application. You can use this as your template and just write hooks into your own authentication system identically.
HTH
I've created a custom authentication backend when I've had to do something similar to what you have to do. See: http://docs.djangoproject.com/en/dev/topics/auth/#writing-an-authentication-backend
In the authenticate function you call your api to authenticate the user, and then map them to a django.contrib.auth.model.User object on some primary key, like username for example. If the primary key is something other than username I usually create a mapping object, or put it into the profile object for the project.
This depends on how you want to handle the problem. If you don't need to keep the existing system running, your best bet is to import their data into the django project.
If the authentication system must stay in tact, you might have to write a wrapper for django.auth. I've done this in the past using SQLAlchemy http://www.sqlalchemy.org to integrate to the external database.
It might be helpful to take a look at the Django 1.2 multi-db support http://djangoadvent.com/1.2/multiple-database-support
In either case I'd try to get the user information into django.auth rather than to write your own authentication system.

Django and Restful APIs

I have been struggling with choosing a methodology for creating a RESTful API with Django. None of the approaches I've tried seem to be the "silver" bullet. WAPI from http://fi.am is probably the closest to what I would like to accomplish, however I am not sure if it is acceptable in a true RESTful API to have parameters that are resource identifiers be in the querystring instead of in a "clean" URL format. Any suggestions for modifying WAPIs RestBinding.PATTERN to "clean" up the URLs? Another option I've explored is Django-Rest-Interface. However this framework seems to violate one of the most important pieces I need, and that is to include the full resource URL for references to other resources (see http://jacobian.org/writing/rest-worst-practices/ Improper Use of Links). The final option is to use django-multiresponse and basically do it the long way.
Please offer me your best advice, especially people that have dealt with this decision.
For Django, besides tastypie and piston, django-rest-framework is a promising one worth mentioning. I've already migrated one of my projects on it smoothly.
Django REST framework is a lightweight REST framework for Django, that
aims to make it easy to build well-connected, self-describing RESTful
Web APIs.
Quick example:
from django.conf.urls.defaults import patterns, url
from djangorestframework.resources import ModelResource
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from myapp.models import MyModel
class MyResource(ModelResource):
model = MyModel
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)),
url(r'^(?P<pk>[^/]+)/$', InstanceModelView.as_view(resource=MyResource)),
)
Take the example from the official site, all above codes provide api, self explained documentation (like soap based webservice) and even sandboxing for testing. Very convenient.
Links:
http://django-rest-framework.org/
I believe the recently released django-piston is now the best solution for creating a proper REST interface in Django. django-piston
Note: django-piston seems to no longer be maintained (see comments below)
django-tastypie is a good way to do it, their slogan: "Creating delicious APIs for Django apps since 2010" is pretty comforting ;)
You could take look at django-dynamicresponse, which is a lightweight framework for adding REST API with JSON to your Django applications.
It requires minimal changes to add API support to existing Django apps, and makes it straight-forward to build-in API from the start in new projects.
Basically, it includes middleware support for parsing JSON into request.POST, in addition to serializing the returned context to JSON or rendering a template/redirecting conditionally based on the request type.
This approach differs from other frameworks (such as django-piston) in that you do not need to create separate handlers for API requests. You can also reuse your existing view logic, and keep using form validation etc. like normal views.
I don't know if this project can be useful for you, but sending a link can hardly hurt. Take a look at django-apibuilder , available from http://opensource.washingtontimes.com/projects/django-apibuilder/ . Perhaps it can be useful?
/Jesper
Have a look at this RestifyDjango.
Somewhat related are Django XML-RPC and JSON-RPC.
https://github.com/RueLaLa/savory-pie
Savory Pie is a REST framework that supports django.
I would suggest you look into Django Rest Framework (DRF), play around with this and see if it suits your requirements. The reason I recommend DRF is because it makes making the API views really simple with the use of GenericAPIView classes, Mixin Classes and Mixed in Generic views. You can easily make use of tried and tested design patterns for making your API endpoints as well as keeping your code base neat and concise. You also DRY when writing your code which is always great. Your API views are literally 2-3 lines long.
You can checkout this tutorial http://programmathics.com/programming/python/django-rest-framework-setup/ that begins from setting up your environment to going through the different ways to make your RESTful API using the django rest framework.
Disclaimer: I am the creator of that website.