Temporary data storage in django which is persistent across browser - django

I'm building a Django where the admin will create a user and then one mail will be sent to the user. In the mail, I'm also sending one token with the URL on clicking which the user will get verified by checking the correctness of the token.
But the problem is I'm storing the token in Django session and when I open the link on the same browser it works but on a different machine user is not getting verified as session data becomes unavailable.
Someone suggest me the best way to store the token.
I didn't want to use the database as it doesn't make sense.

Related

How to maintain user session across different devices and browsers from the access code email link in django

After validating the user, I'm sending out the access token to the user's email, along with the link to come back to the same page.
[![Access Token email][1]][1]
[1]: https://i.stack.imgur.com/OWezf.png
This works well when the user opens the email in the same browser in which he was previously validated, but if he opens the email on his mobile or some other browser and then clicks on the link, he is taken back to the validation page to enter his user details again.
How can I maintain the same session across multiple platforms in Django? I know methods exist that can accomplish that. For example, an API can take an encrypted request id as a parameter, which will be included as a token in the access code email link to the landing page. The API will decrypt the encrypted request id and then return the payload back, associated with the same request id, and the data can then be used on the front end to identify the user and resume the access-code verification step.
But I don't know how to implement that or if there is a better solution.

Can a user barge into django server as another user and perform operatn if he changes info in the frontend if we are using session authentication?

Hey guys I am confused and was thinking about this problem for sometime now, I am storing the current user's username in the session storage, and I have another page in which I use the stored username for an api call, it can be any requests.
Eg. a post can be deleted by its author only, suppose, the url is api/<slug>/delete and in the frontend I have enabled the delete button only for the corresponding user, what if he edits the front end page and changes it to his username or what if I use the stored username to check that condition?
And if he sends a delete request successfully from the frontend, does the django server able to determine that the user in the current session is not the real owner and has tweaked it in the frontend?
Ps. This might be a foolish question, but I am a beginner and quite confused.
Thanks.
Naturally, we would need some code to answer your question.
Will the following delete some other user's data?
A user passes a username from the client to the server
SomeModel.objects.filter(username=username).delete()
Will the above delete the user data whose username is what has been passed from the client? Yes.
You need to always verify and validate data and permissions on the server, and also you should consider using CRUD operations on the current authenticated user (since you are working with sessions), so you don't have to send the current user' username from client, if they are logged in, that can be validated with their session.
I'd advise you to read a little more on Authentication, sessions, ect. authentication in Django
Also, I see you are using A RESTful API, so I would strongly recommend using DRF

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.

Preventing multiple simultaneous logins with Cognito

We have React Native app that uses Cognito for authentication. We would like to prevent the same user ID from logging in simultaneously from multiple devices.
We were hopefully that we could use a Cognito pre-authentication trigger for this. Unfortunately it seems that we can't just call globalSignOut for the user since that wouldn't invalidate tokens that have already been issued and are currently active (see https://github.com/amazon-archives/amazon-cognito-identity-js/issues/21#issuecomment-331472144).
The other idea was to reject the login if the user is logged in elsewhere. But we can't see a reliable way to tell whether the user is already logged in. We can see if there are valid tokens issued for that user but not if they are currently associated with an active session.
We also thought of maintaining our own DB of active sessions but there is no sign-out trigger so we wouldn't know when to remove a session from the DB.
You can use a token authentication system,
Issue a brand new token for each login, and check for available tokens.
if any token is available for the user that means He/She is logged in some other device, for this case you can prompt user that You are logged in other device.. are you sure you want to log out from that device ? and after clicking yes, you can clear all tokens for that user. And issue a brand new token.
AUTO LOGOUT : this token should be passed all over the back-end i.e. in headers of each and every API call token should be there... and should be checked before doing anything in back-end. if token is not available then throw 401. In your app if any API throws 401 then it means user is UNAUTHORIZED and should be logged out.
or
your app should be listening to one socket that responds to log out when it receives a message of same. so whenever your user logs in, a logout message will be passed across sockets and appropriate device with some token id or unique id will get that message and will log out a particular user from all other devices.
or
have a notification receiver which will be used to log out whenever necessary same as socket.
Reading the link you provided the API token / session system seems being faulty by design since long time already.
So without an own token-system inside cognito you won't have reliable results probably, at least in the current state of the system (as the repository is archived it won't be developed further by the owner).
What I propose is an own field in the database-table for users where each login is honored with an own token. A second own field in the same table with a timestamp, where the last access is saved.
If last access is older than a predefined time of 30, 60 or 120 minutes any user gets logged out.
If the last access is younger than the time-limit then the login-mask has to provide a random access token which is compared with that in the database:
- if the access-token in the database is too old for an active session, or just no access-token is stored, then access can be granted which means login is successful.
- the comparison of the current time with the time-stamp saved in the database is for cases where users never have been logged out by purpose but just by being disconnected or passive. I think this case will happen regularly, so it's no exception.
- logging out by click on a button should destroy the access-token in the database, so that the user can immediately login from any device, even from another one then before.
- if there exists a valid access-token in the database then no new access will be granted and the user should get shown a message that he has to sign out first at another login.
- The access-token could be stored together with a third own field for the session-id to make it more reliable and safe. On logout that session-token-field can be cleared too. The session-token can be copied from the global session if required to be saved in the user-record.
- Any checks are only done on login, tokens never have to be included on every page.
- On active logout the token(s) have to be destroyed to allow a direct login again, else the users had to wait till the max. age of the time-limit is reached to login again - at least on another device then before.
As the login itself is currently done independent from the check that has to be implemented, it would be possible to leave the new access-token completely away but use only the session-id as that differs on any device and browser. But perhaps there exists a situation where one of session-id and access-token can change but the other one not - I don't think so but perhaps I missed something in my considerations.
If you provide the access-token on every page like proposed by #Jadeep Galani or in a cookie - beside the corresponding check - you also can offer a button to sign out from all devices. This would enable the users to change login any time even without logging out at the last used device. Without access-token on every page or in a cookie this general logout-function solution is not possible as else access is only checked on login but not on all pages.
A general question is if it's still worth it to rely on the buggy cognito for login or just replace it completely by an own solution. You even could implement the desired authentication in your site in form of a wrapper-class and the concrete login-system could be replaced without changing that implementation.
You can use the UUID of the device to identify whether it is the same user. Add a UUID to each request header to record it in the DB, and then you can do what you want.

Understanding the Client's Responsibilities in OAuth 2.0

I've been trying to learn the inner workings of OAuth 2.0 in my own RESTful app, and I can't seem to find any good explanation of how my Javascript client handles the process.
At this point, I have the client (an Angular 2 SPA) ask the user for their username and password (running Django Rest Framework along with Django Oauth Toolkit). The client makes an AJAX post to the server (specifically to /o/token), and using the resource owner password credentials flow is authenticated and receives the response with the token.
Now, assuming I'm doing everything correctly up to this point, I'm unsure how to properly handle the token from that point forward.
At this point, I'm having my Angular app save the token in a variable and attach the authorization header (with the token) to the calls made to the API. This works as far as granting the correct permissions, but im having a hard time understanding how to maintain persistence of the header (so if the user navigates to a different page, the token is still callable). Initially I stored it in a cookie, but I have concerns with security.
So, first, am I understanding all this correctly? What kind of security concerns should I take into account here? And, of course, how can I save the token on the client?
Yes, you need to store access tokens as user session data because they should be persistent. For example if user leaves your site and then reopens he expects to see himself logged in.
It will be better if you make your sessions server-side: user-agent will store only session ID and all user data will be in your database. User don't need his access token, only your application does.
Instructions for implementation of server-side sessions for Django look pretty simple:
If you want to use a database-backed session, you need to add 'django.contrib.sessions' to your INSTALLED_APPS setting.
Once you have configured your installation, run manage.py migrate to install the single database table that stores session data.