Secret API key for accessing Django REST framework - django

My aim is to restrict access to API for client applications by specifying API Key. Various services allow you to access their API by means of secret Key, which you have to get in order to perfom requests.
Note: this is not related to user auth.
Is there any straightforward solution to do this in django rest framework? Or just to pass the key in request header and then manually handle it?
Regards

Use the TokenAuthentication class, as documented here.
You'll also want to setup appropriate permissions, probably using the IsAuthenticated class.
Edit: Apologies - re-reading you post it looks like you want a global secret key, not a per-user one. I'd suggest a custom permission class that checks for the request header and fails if it's not present/not correct.

There is a third party app now for this purpose called django-rest-framework-api-key.

Related

Flask authenticantion. How to inform the user logged in the client to the server

I am creating a flask app to be used internally in my company. I would like to restrict what a user can do it based on its login ID. I read a lot about using LDAP3 but I don't think I can do what want which send the login ID to the server. There I would have a table which will register which part of the system has the permition to edit. If it try to change somenthing not permited the app will retrieve a warning message.
I won't to do that to avoid having to create a separate login functionality just for this app. I read that I should use AD authentication but I am not very familiarized with that and I would also like to avoid having to ask our IT department to create user groups there for each part of my system.
I know that I can do that using ASP .NET (at least I did once).
Any guidance will be apreciated.
I think you are looking for Role-based Authorization.
In order to use this functionality you will need to implement roles on your model file per the Data-models documentation.
This will allow you to assign users a role when they are created, and you can use a decorator on your routes to 'require' the user to have the role you want them to have before they access the endpoint.

How To Secure Third Party API data using Django?

I'm using a third party API Key for my website. I have done some modification on that API and now I'm using it for my own site.
I want to secure that API data by adding a restriction on any user (Authenticated or Anonymous ).
I want to add a time limit on the data provided by the API. So, if anybody uses the same data after a certain period of time then it will show an error.
As well as I want some restrictions on users IP. So, a user can access my website a fixed number of time.
You might want to use the Django REST Framework JWT Authentication.
I implemented https://github.com/davesque/django-rest-framework-simplejwt
It works - the installation is rather easy - read the docs :)
if you are using DRF use the authentication class settings. If you are using normal Django views you can wrap the view with a login_required decorator

Is there a way to make a Google Place Photos API request without exposing the API Key?

I'm making a web-app where I need to make a request to the Google Places API, this is all good but I also need to make a request to the Places Photo API to display the images of the stuff I find using the places API. To do this, you need to make a request like this:
https://maps.googleapis.com/maps/api/place/photo?parameters
Where one of mandatory parameters is your API Key. I'm using Django and I'm passing a dictionary that has all the info I need to display. However, in the frontend you can see the API Key in the URL of the image. Is there any way I can avoid that?
Thank you so much!
You cannot avoid using an API key. All calls to the Maps APIs need to pass an API key to be able to work.
However, you can secure your API keys with restrictions.
You may follow these instructions to restrict your API key for Place Photos use.
Hope this answers your concern.
The Places API is a server API and can not be restricted by referrer. If you try then you get a 403 response to every request. You can't use it client side with an IP restriction, so the only restriction available is to limit it to the places API. This is not ideal since some of the places API calls are chargeable.

Understanding SessionAuthentication in django-rest-framework?

I am using Django v1.8 and django-rest-framework v3.2.2. I have a site with a public-facing API, which is also consumed by my own site (on the same domain) as the Ajax back-end to a JavaScript application, using GET only.
I want public users of this API to be asked for a key parameter in the URL, which I will issue manually. But I also want my JavaScript application to be able to use the API, in a way that means that other users can't just steal the key and use it.
I have set up my custom key authentication as described here, and it's working well.
However, I'm unclear on how the JavaScript application should use the API. Obviously I could just pass a dedicated key parameter in the URL, but then won't other users trivially be able to spot the key and use it?
I think I need SessionAuthentication, but how do I even start to make this work? I can't see any instructions in the DRF documentation about how I need to change my JavaScript calls to use it.
Also I don't understand how SessionAuthentication allows the Ajax app to authenticate without other users being able to see and copy the authentication.
Very grateful for any advice.
I think I need SessionAuthentication, but how do I even start to make this work? I can't see any instructions in the DRF documentation about how I need to change my JavaScript calls to use it.
SessionAuthentication is the Django's one. It uses session to authenticate a user. It's mostly transparent for ajax request as the browser will send the cookie automatically. However, if you're posting data, you need to make sure you send the CSRF token in both headers and post body.
Also I don't understand how SessionAuthentication allows the Ajax app to authenticate without other users being able to see and copy the authentication.
As said above, it uses cookies for that. They are part of the headers and thus usually not seen on the urls.
To make sure no-one else can steal user's session you need to run the site through https.
This isn't much different from regular websites.

object-level permissions django

How do you ensure that a User can only edit objects they've created? What's the best way to set this up?
I'm using django-rest-framework and wondering if there's a way I can restrict users from viewing/ editing objects they don't 'own'.
class Video(models.Model):
owner = models.ForeignKey(User)
...
So User 'x' should only be able to edit videos in their owner_set.
Presumably you have sessions and the auth model turned on.
You must be sure that all views (REST and non-REST) require authentication.
For non-REST, it's easy. You simply use a basic #login-required decorator everywhere.
For the Django-REST Framework, read this: http://django-rest-framework.org/library/authentication.html#module-authentication.
You have to use the authentication mixin to be sure that authentication actually happened.
The framework supports BASIC Authentication, which requires an SSL connection to be secure. It's not too difficult to implement DIGEST authentication, which doesn't require SSL.
Avoid sessions. It violates a principle of REST to login and logout. The framework supports sessions, but it's less than ideal.
Once you have all requests authenticated, you'll know the user.
If you know the user, then user.video_set works perfectly. You can also use Video.objects.filter(...) to be sure that you're querying the user, but it's easier to confirm the code is correct if you work with user.video_set.get(...) or user.video_set.filter() or whatever.
All the relevant authorization checking is done in Views. You're providing Views for your ModelResources.
These are "class-based views". Documentation is here: https://docs.djangoproject.com/en/dev/topics/class-based-views/#viewing-subsets-of-objects
The trick is to pick all the right mixing and serializers.
For example, you can mixing get processing this way:
http://django-rest-framework.org/howto/mixin.html
You'll implement the filter in the get method