Django REST framework: token authentication with HTML frontend - django

I want to use token authentication with HTML frontend (like in this tutorial http://www.django-rest-framework.org/topics/html-and-forms/ where they show how to render login form, but not how to actually login).
I have already a login function that returns token, but I don't know how to make web browser remember it and redirect somewhere else.
It is probably possible to pass the token to every template, but it seems a terrible practice

I have taken the help of Sessions in the browsers. You can store your token in the session of the browser and whenever you need it just fetch it.
$window.sessionStorage["token"] = response.data.token;
this is how I am storing it after my LOGIN API and store the token into session. To retrieve I use something like below:
headers: {
'Authorization': 'Token ' + $window.sessionStorage['token']
}
You can look into how to secure your sessions into the browser, also when logging out you can just destroy the session values.

Related

How to implement token authentication using httponly cookie in Django and Drf

I'm building an application with django , Drf and currently using vanilla JS as Frontend for now.
I searched almost all through web on different use case for authentication on the web and I found out different links but these links seem to always favour the session authentication and token authentication.
Using Django helps us with the session authentication as default so I decided to study the auth process using a token auth.
While doing this, I initially used the localstorage as a store for my tokens gotten from the backend response after user authenticates, But for some reasons which are valid , most devs/engineers advise against using the localstorage as it prones one to xss attacks..
So I decided to implement the httponly cookie method, but I haven't seen a practical use of this done on Django, I've seen theories on implementing all these but haven't seen someone done this..
Please how can I use the httponly cookie with my token stored as a cookie with DJANGO
EDIT
I know a httponly cookie does not allow JavaScript to access a cookie, so I decided to do this.
Django sends the cookie httponly with the token as the cookie
User makes a request to the backend
server gets the token from the cookie sent as a request from the backend.
4)"where the problem now comes" I can't set the token as an header in Django, I tried using the request.headers['Autho...] = Token ....
But that doesn't allow item assignment..
So if my logic is correct this is where I'm stucked
EDIT So this time, I am now able to add a header from the server , using request.META to pass an Authorization key with the Token .... Value, that seems to work fine instead of having to use request.headers for passing an assignment..
But something happened which shocked me, in as much as I'm able to change or add an authorization token from the server , the view still gives me an error, much like I never passed a token at all.....
It's like after the whole efforts and everything nothing still changes, except if it's requested from the client side 😢.
Guess I will have to stick with localstorage for now, but still research more or wait for answers .
I've done the Authentication with token using httponly cookie..
I recalled when I asked questions and some loving guys from here helped tho, we couldn't see a straight off answer as we had to research and think as well...
The steps I used was this.
Django takes in user credentials
Django authenticate that credentials
a token is exchanged for that data
we set the token to a cookie using
set_cookie(.... , httponly=True)
** Then it was now time for the real workout .
I created a middleware which will be responsible for setting the token to an Authorization key in header dict.. instead of allowing the client to do this.
---- The client couldn't handle this coz it was now a httponly flag which will prevent js from accessing it as the purpose of using httponly was for this to prevent xss attacks when tokens/cookies are normally stored in a browser storage
we then handle the middleware to our taste, as in mine I tried making sure it work for only some views and not all views (will be planning on making a custom decorator for it)
then last was to 🤔🤔 we'll have fun and smile at seeing me create something as such without a previous tutorial...
The GitHub repo link https://github.com/HarryAustin/tweeter-DrfTest-httonlycookie

How to authenticate the user on his requests after login in django using TokenAuthentication from drf

I have implemented an endpoint for login, using the django-rest-framework and TokenAuthentication. What i want, is after the login, the user to be authenticated and can navigate on the website.
I know that any get request on any protected using authentication uri should contain the token in the headers, so that the user can be authenticated. Everything is fine with that, if i could do all the get requests adding the token manually.
But what i do not understand is, how can i add the token in the headers when for example the user manually does the request by writing the url?
Let's say that the uri /api/ is protected and requires an authenticated user.
The user logs in, and i save the token either on the cookies or in the localstorage.
Now the user does a http get request on /api/. The token is not placed in the headers, so the response is: "Not authenticated".
So the question is, how can i add the token on any subsequent request after user logs in successfully? Maybe the backend could check the cookies for a valid token, but isn't there any better and safer solution than this?
As I believe from the question you want to add the token to all API which is consumed by your client whether App/Web. So in both people prefer to store that token either in cookies or in local storage. Once user logged out api consumer also flush that key.

Django REST framework - prevent data access for user view?

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

How to make REST api calls that needs auth_token?

I'm working on a Django-REST application that contains APIs that work with login mechanism.
I'm able to create API endpoints for login and logouts.
Login takes username, password and returns auth_token which is around 30 characters.
Logout takes auth_token and destroys it.
In between these login and logouts, there are few API calls that make use of auth_token.
How is it generally implemented ? How are the requests made with auth_token in general?
Where are those tokens stored? How do the backend validates it?
Can someone please explain me how it is done basically?
store the token in browser storage. and remove the token form browser storage on logout logic.
make sure you drf setting DEFAULT_AUTHENTICATION_CLASSES list contain TokenAuthentication class before SessionAuthentication , rest_framework.authtoken in you setting install app.
for any api call just attach the token like (Token your_toke) I mean "Toke" then space the your token and attach it to your request authentication header of the ajax request

Working with django rest framework to authenticate a user with new token for every login

I would like to use django-rest-framework token to authenticate users. My workflow would be:
User requests a page
If auth token is present, respond with the requested data.
If auth token is not present, redirect to the login page (with the request page).
Inside the login page, user submit their credentials
If credentials were correctly authenticated, get or create a token for that user and redirect back to the requested page with the token.
Else, respond with error.
Lastly,
When the user logs out, delete the token for that user.
So my question is, is it okay to delete and create a new token for every login if the user has already logged out? Also I assume the token will be unique, am I correct? Your help and guidance is very much appreciated. Thank you.
A REST API should be stateless, that means that there should not be a "session" hence no login and no logout, and no redirections to a login page.
If the request doesn't have a token then the API should return (probably) a 401 Unauthorized HTTP status code and not a redirection. You're making an API so there won't be human interaction. Django rest framework offers a human-friendly interface that does have sessions, login/logout, and if that's all you need the go for it, you can do whatever you want. But It'd be hard for another program to use your API.
why not using tokens with expiration dates or using another well known authentication method ?? :P
Hope this helps :)