Django Rest Framework without authentication + GET only - python

I am developing a back-end for a webpage using Django Rest Framework. The webpage will be public, and it will only fetch information from this service. Thus, I have to deploy both service and webpage.
Since the webpage is public access (without any type of login) I can avoid having to set up the SSL stuff. However, by default, the DRF comes with the browsable API and the login field. I know I can remove the browsable API, but is it enough?
For instance, the configurations I would have would be:
(removing the BrowsableAPIRenderer)
'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.JSONPRenderer',
'rest_framework_csv.renderers.CSVRenderer', )
and:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
'GET',
'HEAD',
'OPTIONS',
)
I am using https://github.com/ottoyiu/django-cors-headers for the CORS stuff.
Would this be enough to avoid unwanted login atempts? Is there any specific way to disable this option?
What 'DEFAULT_PERMISSION_CLASSES' shoul I use?
Best regards and thanks for any help!

If you have a login, but you don't have SSL, then your users are vulnerable to packet sniffing of credentials on many wifi and ethernet networks. Such a vulnerability can be trivially exploited with the Firesheep firefox plugin. Due to users' habit of reusing passwords, you could end up compromising their security to a more critical website. This is very unfortunate. It isn't entirely your problem if users reuse their password, but SSL should be a base layer of protection to your users.
While it is possible to use Django templates with Django Rest Framework (DRF) as the backend, you are not limited to using Django for your front-end. Consider AngularJS with DRF. Anyways, there is a significant learning curve for AngularJS, but you needn't limit yourself to having Django supply your front-end.
As far as removing the DRF BrowsableAPIRenderer, you will get some protection from "security through obscurity", but you really need to lock down your APIs through a proper permission model as an attacker can easily look at traffic generated by your front-end to your back-end and then manipulate the requests to your back-end. So, discoverability of your interface by an adversary will not be significantly reduced through getting rid of BrowsableAPIRenderer. It will only obscure back-end resources that your front-end isn't currently using and it will also make your life as a front-end dev a little more painful.
For DEFAULT_PERMISSION_CLASSES, take a gander at DRF permissions documentation. If you only have two user groups - logged in/authenticate and not logged in, then IsAuthenticatedOrReadOnly is a good place to start. If you start to have per-model permission bifurcation for different user groups, then
DjangoModelPermissions is a good place to dig into.

Related

User management in Single Page App + REST backend

What is the best way to do user management in a single page JS (Mithril) app? I want users to login to load preferences and take on a role so they gain certain permissions. I have a REST API backend written in Python (Falcon web framework). Having read a bit into it, it seems to boil down to sending credentials to the backend and get a token back. But the question is how that should be done. It seems that tokens are a better method than cookies, but that has effects on the exchange of secrets/tokens. the 'xhr.withCredentials' method seems to be cookie based for instance. JWT (json web tokens) seems like a modern, interesting option, but it's hard to find a clear explanation how it could be used with a SPA.. And once the Mithril app has a token, where should I store it and how should I use it with subsequent requests?
This isn't so much about Mithril, actually the only Mithril-related area is the server communication. That is done with the m.request method (docs here), but you need to create an object for all server communication that requires authentication.
That object should have knowledge about the auth system and detect if a token expired, then request a new one, take proper action if things fail, etc. It's a bit of work, but the process is different for most auth systems, so there's not much to do about it, except using something that already exists.
Being a small and lean MVC framework, Mithril doesn't have any security-related features built-in, but the m.request method is very powerful and you should use that inside the auth communication object.
The client-side storage will be in cookies or HTML5 storage. Here's an StackExchange answer that goes into more depth: https://security.stackexchange.com/a/80767 but the point is that this isn't Mithril-related either.
Thanks for linking to the tokens vs. cookies article, it was very nice!

AngularJS and Django REST framework cookies

I have a problem regarding AngularJS using Django as backend. The Django framework has its authentication system, using its csrftoken.
The thing is, that over the client side, i need to make sure that the client is logged in, to let him see AngularJS' views. The problem is that the $cookieStore returns undefined when asking for the Django cookie ( $cookieStore.get('csrftoken'); ).
Currently i'm adding the auth token, by sending it in the response body from the server ( $cookieStore.put('authToken', responsePody.session_key) )
After adding the cookie 'manually', i'm manipulating it (removing when user logs out etc..)
My question is how can i access the Django cookies using cookieStore, or if there is a better way of implementing this?

Which authentication to be used when using Django Rest Framework and IOS app?

I have an iOS app that uses an API powered by Django REST framework to store, update, fetch data from a database. I need to provide the two more following functionalities which stores the user data at the server:
Login with Email
Login with Facebook
There appears to be two different authentication systems that I can use:
Django User Authentication System
Django Rest Framework Authentication
How should I handle this in my API?
When you are using Django REST framework with iOS, unless you are using a browser, the standard Django authentication system is out of the question. This is exposed through the DRF authentication system as SessionAuthentication and it relies on your application being able to transfer cookies and the CSRF token with the request, which typically isn't possible.
In most situations where you are using the Django authentication system already, and you can trust your app storing passwords, you would use something like BasicAuthentiction. Most people can't though, or they don't trust their application ecosystem, so they use a token-based authentication system like TokenAuthentication or OAuth2Authorization (in combination with an OAuth provider). You can read more about each authentication type in this answer on Stack Overflow.
But in your situation, you are basically restricted to just using something like OAuth 2. This is because you need to associate a user with a token, and most authentication systems require you to provide a username and password. For social accounts, this usually isn't the case, and they would not normally be able to log in. OAuth 2 works in combination with the standard Django login, so you are not restricted to just a username and password. I've written more about how this works in this detailed Stack Overflow answer.

Appropriate choice of authentication class for python REST API used by web app

I would like build a REST API using the Django REST framework. Initially its client would be a web application, but conceivably future clients could include mobile applications.
Unfortunately I'm finding the list of authentication classes listed in the documentation a little confusing. It looks like TokenAuthentication would meet my needs. I would rather avoid the cognitive overhead of OAuth unless there is a compelling security reason to go that way.
This is a decision I want to get right at this very early stage. Can anyone provide any advice?
Edit: Although hopefully not relevant, I thought I'd mention I'll be using Neo4j as a back-end for the application, not a conventional SQL database.
Django REST Framework gives you the flexibility of having multiple authentication methods. Since I've got some time, and it will be useful to future visitors who have similar questions, I'll outline the benefits of the most common authentication methods.
Initially its client would be a web application, but conceivably future clients could include mobile applications.
Typically when working with web applications that are on the same domain and Django instance as the API, most people use SessionAuthentication as it interacts with the server using the existing authentication methods. Authentication works seamlessly, so you don't need to go through the second authentication step.
Most APIs also support some form of BasicAuthentication, most likely because it is the easiest to test with but also because it is the easiest to implement. For your web application, this isn't the recommended authentication method, but for your mobile application it's not uncommon to see it being used. I personally would recommend a token-based authentication, so you don't have to worry about clients intercepting user's credentials.
It looks like TokenAuthentication would meet my needs.
Many people use TokenAuthentication because it is relatively simple to understand and use, and it seems to meet everyone's needs at first. Tokens are directly attached to users, and they do not automatically rotate (though you can make them automatically rotate), so every client working on behalf of the user gets the same token. This can be an issue if you ever need to revoke the token, as all other clients will have their token invalidated as well.
I would rather avoid the cognitive overhead of OAuth unless there is a compelling security reason to go that way.
OAuth 2 (OAuth2Authentication) gives you token rotation and token expiration on top of the benefits of TokenAuthentication. There's also the benefit of being able to revoke individual tokens without affecting other clients who are authenticating for the user. You can also limit clients to individual areas of your API through the use of scopes, which is useful if you have certain areas of the API that are more often used than others.
I'm also going to mention JSON Web Tokens, because while I haven't used it, it's been showing up quite a bit in the support channels. It works very similar to TokenAuthentication as far as retrieving tokens, but it has the added benefit of unique tokens for clients and token expiration.

django-allauth with multiple domains

I am creating a web application that will support several domains. For example, if my app were named www.webapp.com, I'd also have numerous customers mapping their domains to my site via DNS CNAME mappings, i.e. webapp.yourdomain.com CNAME www.webapp.com and foo.anotherdomain.com CNAME www.webapp.com, etc...
I want users to authenticate against my app via Google or Facebook (OAuth 2.0) - without me (or the domain owners) having to create a separate Google/Facebook app per mapped domain. Ideally, I would have the base domain act as a broker and redirect to the appropriate mapped domain when responding to the callback url. For example, a user visiting webapp.yourdomain.com/accounts/facebook/login would authenticate against Facebook with a callback url going to www.webapp.com/accounts/facebook/login/callback. When processing the request, I could find the appropriate context, and redirect to webapp.yourdomain.com/accounts/facebook/login/callback where the real authentication would take place (and domain-specific auth cookies would be set).
So, is this doable in django-allauth? How much hacking would it require? Or, is there another social authentication solution for Django that would be easier to implement this in?
You should use Django sites framework together with django-allauth.
Consumer keys, tokens make use of the Django sites framework. This is
especially helpful for larger multi-domain projects, but also allows
for for easy switching between a development (localhost) and
production setup without messing with your settings and database.
Just configure each social app in the admin backend.

Categories