Django REST framework - prevent data access for user view? - ember.js

In my api, I have a /users endpoint which currently shows (eg address) details of all users currently registered. This needs to be accessed by the (Ember) application (eg to view a user shipping address) but for obvious reasons I can't allow anyone to be able to view the data (whether that be via the browsable api or as plain JSON if we restrict a view to just use the JSONRenderer). I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
Am I missing something?
UPDATE
Hi, I wanted to come back on this.
For authentication on the Ember side I'm using Ember Simple Auth and token based authentication in Django. All is working fine - I can log into the Ember app, and have access to the token.
What I need to be able to do is to access the user; for this I followed the code sample here https://github.com/simplabs/ember-simple-auth/blob/master/guides/managing-current-user.md
I have tested the token based authentication in Postman, using the token for my logged in user - and can access the /users endpoint. (This is returning all users - what I want is for only the user for whom I have the token to be returned but that's for later!).
The question is how to do I pass the (token) header in any Ember requests, eg
this.store.findAll('user') .... etc
This is clearly not happening currently, and I'm not sure how to fix this.
UPDATE
Fixed it. Turns out that the authorize function in my application adapter was not setting the headers, so have changed the code to set the headers explicitly:
authorize(xhr) {
let { access_token } = this.get('session.data.authenticated');
if (isPresent(access_token)) {
xhr.setRequestHeader('Authorization', `Token ${access_token}`);
}
},
headers: computed('session.data.authenticated.token', function () {
const headers = {};
if (this.session.isAuthenticated) {
headers['Authorization'] = `Token ${this.session.data.authenticated.token}`
}
return headers;
})

Ember is framework for creating SPAs. These run in the browser. So for Ember to get the data, you have to send the data to the browser.
The browser is completely under the control of the user. The browser is software that works for them, not for the owner of the website.
Any data you send to the browser, the user can access. Full stop.
If you want to limit which bits of the data the user can read from the API, then you need to write the logic to apply those limits server-side and not depend on the client-side Ember code to filter out the bits you don't want the user to see.
I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
This doesn't really make sense.
Generally, this should happen:
The user enters some credentials into the Ember app
The ember app sends them to an authentication endpoint on the server
The server returns a token
The ember app stores the token
The ember app sends the token when it makes the request for data from the API
The server uses the token to determine which data to send back from the API

Related

How to pass in the token for authorization in between React pages (in a Django Knox setup)?

I have 2 components/pages. One is the login page and one is the user customization page. I want the user customization page to be token authorized so you can only see it after you login.
I am using a Django + React setup with Django Knox being used as the authorization tokens.
I now have a workflow using this.props that passes the token from the login component to the main app.js and then to the user customization component. But I guess during the routing/switching between pages, my token is lost. How do I maintain this token?
So, basically trying to persist your token, without having to refetch it when (for example) the page is reloaded or, as you mentioned, when navigating between different pages in your application.
There are various ways to store the token, without much work, one such example being sessionStorage
// API response
const token = response.data.token
// write to storage
sessionStorage.setItem('myTokenName', token)
// read from storage
sessionStorage.getItem('myTokenName')
// delete from storage
sessionStorage.remove('myTokenName')
With plain JS:
sessionStorage
localStorage
cookies
NOTE: Each has it's purpose and limitations
With additional libraries for state management, although this requires more work, and is not necessary to fix your issue.
Redux
Apollo (assumes you're using GraphQL)

Is saving user's id and login token in local storage a good idea?

I am developing Django + React project and I'm caught with this security approach concerning login and managing views for the logged in user.
I am using django-rest-framework or DRF for my RESTful API. And I'm using django-rest-knox for authenticating user logins since I am implementing Token-based authentication (instead of session-based which uses CSRF).
Question: Is it a good idea to save user's id and token in local storage?
Currently, I have a /auth/login/ API endpoint that handles the backend logic of logging in user and returns JSON response of login details upon successful login (including user id and token).
In my frontend, I use redux and redux-persist so the user's login details are kept even when the site is refreshed. The way redux-persist do it is that it saves the response in local storage. This means that the user id and token can be accessed and changed anytime thru dev tools.
If user will then make a POST request to an API that requires a Token authentication header, the frontend will look into that local storage for the token value to be supplied to the request header.
If user will then make a POST request to an API where the user id is required in the request data, the frontend will also look for the id in the local storage.
Localstorage is not safe, especially for storing tokens and ids. Any user can go to the browser's developer tools, see and also edit its contents, for example.
You could check on Django's sessions, so you can store data securely at server side and keep its contents associated with a specific user. There is a great tutorial at Mozilla that explains sessions in a clearer way than the official documentation.

Firebase Token Authentication using Django

I am new to django and am trying to get the user authenticated using firebase admin sdk. I am trying to do token authentication and have setup the admin sdk in my django app. Also I have received the client id token in the android app.
Now I am unable to understand how to send this id to the backend and verify it as a user and create users accordingly.I did find this answer but couldn't really understand how to go about this.
Also if a user is verified how do I add and update its data. Do I pass the token again or is there any other way to do it?
Your Android App should send its ID token along with all requests sent to the backend server. You can decide how to include that (as a header, as part of a JSON payload etc). In the backend server, you should always call auth.verify_id_token() and return an error (e.g. 401 Unauthorized) if the token fails to validate.

Django-allauth, JWT, Oauth

I have an AngularJS Single Page Application that uses a Django backend API based on the Django Rest Framework. The API is protected via django-rest-framework-jwt. I would like to use django-allauth for account management and authentication on the server side.
I am just missing one single piece in the flow: How does my Oauth-Token from the client get transferred into a JWT-token? Basically, I would like to do as described here http://blog.wizer.fr/2013/11/angularjs-facebook-with-a-django-rest-api/ based on python-social-auth.
So my question is, how do I implement the ObtainAuthToken class from the link with django-allauth?
There are usually two login flows with social login: client-side ("Javascript SDK") and server-side. If your server needs to be authorised, it's usually a lot easier to go through the server-side flow. And that's also what all-auth does I think (and you didn't mention you use a frontend library like the blogpost you mentioned does).
Now the challenge is to provide the token from the server to the frontend. You would probably load the token in the HTML of the initialisation of the SPA, and then from Angular save the token client side (cookie, localStorage, etc.) so the session isn't lost on a refresh.
If you don't want the user to leave your app, you can open your /accounts/login/ or /accounts/signup/ url in a new window. In that new window they authorise your app, and your server receives the token upon return. There, you will have to generate a JWT token manually, and render that into the template so that javascript can access it. With js in that popup window, you can then communicate with your app that opened the popup and pass it the token – see this SO answer for an example – so it can save it.
Django-allauth provides signals that let you hook into the social login process. In your case, I would recommend subscribing to the allauth.socialaccount.signals.pre_social_login signal. The code will look something like this:
from allauth.socialaccount.signals import pre_social_login
#receiver(pre_social_login)
def create_jwt_token(sender, request, sociallogin, **kwargs):
# dig into the sociallogin object to find the new access token.
We used hello.js for O-Auth at the company I worked at.
You provide a shim on the Python end and get the refresh token and whatever other data needed once the user connects their social account.
We redirect them via Django to the page they attempted to access from their OAuth provider's page.
Each user still has their own email account which is needed for the JWT, but you could assume that whatever email is in the scope of their social account is their email then use django's functionality to create new users: User.objects.create(email=emailStringFromOauthData) etc.

How to login a Django account from an iOS App?

In my App I need to communicate with my Django website. Some resources require authentication so I need user login.
But this does not happen in a browser or a web view. I need to use Object-C to issue a login request and handle the response - basically to store the session ID I guess.
On the web server side, how should I do this in Django? To have a stand-alone view for that and return JSON maybe? How can I get the newly generated session ID though?
I wouldn't get the session ID. I believe logging in a user is more geared toward a web interface. I would create an API that serves the resources you need in your app. http://en.wikipedia.org/wiki/Representational_state_transfer Authentication would probably be best suited for a private/public key pair or some other similar popular api authentication system.
You don't need to make any changes to your authentication system, save for maybe making sure the login form is usable on the smaller screen. Cookies work the same on iOS as they do on the web. You can display a modal UIWebView with your login form. After the user logs in, presumably you are setting a session cookie. If you make a subsequent request to the domain the cookie matches, the cookie should be sent along. You want to look into the HTTP 'Accept' header field, which specifies the content type the client expects to receive. In your controller (view?), you'll want to check the 'Accept' header, and return the appropriate content type, probably 'application/json' (or a custom type for your API).