Should I use JWT or Sessions for my eCommerce website? - django

I'm building an eCommerce website for a personal project. It uses React for the front-end and a REST API running on django for the back-end. I want the user to be able to add items to a shopping cart and place an order without the need for an account.
For guest users, using a session/cookie to store info is great, but when it comes to logged in users, I would want to use the database to store items in a cart. That would require creating a user and giving them an auth token so they can perform necessary actions.
So should I use session/cookie authentication or is there a better way to achieve what I want using JWT?

Both approach can work very well. However, I am currently working on something similar and I would personally recommend the simpler option which is the classic session approach. JWT tokens can be harder to maintain and sometimes insecure if not done correctly. Also, JWT tokens will not persists between logins.
In both ways, I don't see why one would be better to create and maintain a cart except maybe that a session system can actually store the complete cart in the session itself. You can then implement sessions controllers at the API level.
ex: GET "https://{host}/api/cart" returns the items in the session's cart.
# Django session
request.session['cart_id'] = cartId
# JWT Tokens
jwt.encode({‘cart_id’: cartId} ...
little note.. It can be harder to setup the sessions if you are working on localhost for react and a remote server for your API. (The cookies are generally set per domain).

I am using JWT, and I think if you are using a database, you can create a generated JWTby user then store it in the database, you can control the availability of your jwt, in parameters, and I find the best way to secure your APIs, is to add the JWT token to the headers.

I would use Cognito authentication and integrate it with react and the backend api. It will help to manage the users outside the application.

If you’ll be hosting your application in AWS, Check out AWS Cognito, it’s an identity and a user pool service. Their free tier is quiet generous. That, together with AWS Amplify which is perfect for React, will give you out-of-the-box auth and user management.

Related

Can I use AWS Cognito token(s) to verify users across applications?

I have multiple applications such as:
user.myappsite.com/app1
user.myappsite.com/app2
user.myappsite.com/app3
A user logs in using their cognito login on any given application. Problem is if they go to another application they have to log into that one as well. I'd like to use a token created at login to verify the user on other apps so they don't have to login multiple times.
I'm sure this is possible but not finding anything helpful through the docs or searching.
Depends on how your app is constructed. The issue is you need to store the login state somewhere in your application. If you are using an SPA you need to use a store. If this app has a server involved you can use server side sessions.
In the case of a server whenever the user visits a page you need to verify that they have a valid session before proceeding.
In the case of an spa you only need to verify once when the page initially loads and prevent your app from rendering unless that token exist.
Keep in mind with an spa your apps insides are all exposed so make sure any sensitive information your app provides only comes from a place that verifies tokens first (like api gateway).

How to use AWS Cognito as a unified SSO?

I would like to have only one login screen, registration, profile and password recovery for all projects in my company. Basically a unified login or SSO.
So I made these screens using AWS Cognito and hosted them on the sso.mycompany.com domain and it's working fine.
But now I need to implement these screens in my other projects. How can I do this? I can't just copy the files, as this was done in Vue.js, and I would like to put these screens in projects done in Laravel, Wordpress, React, etc;
I thought of using an iframe loading sso.mycompany.com, but how do I return user data after login to the app that opened the iframe?
Basically that's it, I have authentication screens hosted on the sso.mycompany.com domain and I would like to use them on projectx.com, projecty.com, mycompany.com, etc.
Here is one solution that might work for you and might give you some ideas on how you could put together a solution. Unfortunately, Cognito out of the box doesn't come with a unified/universal login experience that you require. It also doesn't come with a lot of other features you might see from the big IdP platforms, but that is another discussion for another time :) The whole foundation of this solution is based off of a single domain, cookies and JWTs(access token, id token and a refresh token). It will still work for your apps on other domains, but the experience for your end users will be a bit sub optimal compared to if all your apps were on the same domain.
Because an app like projectx.com sits on a different domain then sso.mycompany.com, you have to somehow get a access token over to projectx.com after the user logs in through mycompany.com. You can simply just pass the access token through as a query param when you redirect the user back to projectx.com after a successful login on sso.mycompany.com.
I had a much longer answer with details, but stackoverflow won't let me post because it thinks my answer is spam??? Check my profile on how to contact me if you want the longer version with details.

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.

Django Google Login with React Frontend

This question may be super simple but I've been googling for a while now and haven't found an exact solution.
I'm trying to implement a Google Login using React for the frontend and Django for the backend.
How exactly would I do this? I have seen solutions where a token is sent over to the backend which then retrieves the necessary information from the Google API and either creates or retrieves a user from the database based on the token. However, this seemed to be based on JWT and I was wondering if it is possible to implement the same with the simple Django Auth Token?
Maybe I'm just really blind but I really wasn't able to find a suitable solution.
Thanks for your help!
I was actually working on this a few moments ago, after many fails in the past. It's quite a headache really trying to find a solution that works with React. I have however managed to easily setup google login on the React front end side with https://www.npmjs.com/package/react-google-login. This should be the first step you will need to take.
After that you will need to setup social login on the Django backend using django_allauth. Basically, the idea is once a user logs in via google or to be precise, clicks on the Login With Google button on the front end, a google access_token will be retrieved from Google and saved in local storage together with some other data. Only the access_token is of interest here. So you will then need to take this access_token and send it to the Django backend via a Rest API of a view that you will have setup. That will get the google user data saved in the database under social accounts, ultimately login them in the application. Everything from then on should continue as per your normal logins with email and username. That is if using JWT, a jwt token will be returned from the backend which you hopefully should be able to save in local storage. In my React app, I authenticate against this token, so as long as I have the token in local storage, a user is logged in.
Pratik Singh Chauhan does a good job explaining this in his Part 1 tutorial here -> https://medium.com/#pratique/social-login-with-react-and-django-i-c380fe8982e2 and Part 2 here -> https://medium.com/#pratique/social-login-with-react-and-django-ii-39b8aa20cd27
UPDATE: June 2022
Since Google is now moving to (GIS) Google Identity Services sign-in SDK, this method, although it works is now deprecated.
Here is a good link to help you setup react login with the new google GIS.
https://github.com/MomenSherif/react-oauth/issues/12#issuecomment-1131408898
There are 2 methods you can use depending on your workflow, implicit or authorization. To maintain a similar workflow that the above code achieved, implicit workflow is the one that can give you both access_token and refresh_token that you will send to your backend api.
Here is another link with sample code for both workflows.
https://react-oauth.vercel.app/
Note you will need to use #react-oauth/google to configure the Google workflows in your code.
Refer to this:
https://reactjsexample.com/google-oauth2-using-the-new-google-identity-services-sdk-for-react/

Multi-tenant Centralized Authentication Server

I am trying to create a centralized authentication server for multiple Django apps (APIs). I've seen posts/recommendations but none fit exactly what I am looking for.
Overview:
Users can be associated to one or multiple projects
Users have same credentials to all projects they are associated to
Use JSON Web Tokens - use payload to add user data, sub-domain (project) to route to, role, etc
Sub-domain will not be used for login. All users will login to same site and will be routed to project they are associated to (or given list if there are multiple). SSO is optional.
Questions/uncertainties:
Q: Should the authentication tokens be created on the authentication server or on each project? ie) Each user having one auth token for all projects or have one auth token for each project?
Q: Roles will be stored in each app. I would like to send the roles along with the authentication token in the JWT. Should this data be redundantly stored on the authentication server? Another other way would be for the authentication server to access the project databases. What is the best way to handle this? Users will have different roles for each project.
Q: Auth server will have basic user information (email/username, password, first/last name, etc). Since foreign keys can't be used between databases I can use a user proxy based on usernames to create the user on each project. Do the app servers need to have access to which authentication tokens are valid?
Taking advantage of pre-existing software:
Another approach I had in mind was to use django-tenant-schemas which takes advantage of Postgres schemas where each one of my projects would be a schema (currently using MYSQL databases). Does it make sense to take advantage of this?
Can I take advantage of an IdP service to offload some of the authentication? Does this easily tie into the Django auth layer?
Your question seems to be multiple so I would split the answer too:
ABOUT THE USERS
Since your users are not part of your "mutitencancy model" you have two options here:
Replicate your user data among the different tenant databases (via triggers and what not).
Write your own authentication middleware that verifies users in the right database (lets call it root database since now on). You can use user ids to from the root database and verify manually that they match, which is a bad idea.
That means your database schema will be something like this:
root database (all common data here)
project 1 database (with it's own user data or referencing root)
project 2 database (with it's own user data or referencing root)
Now for authentication tokens
You have the same options as above:
Keep them in the root database and write your own middleware.
Replicate them.
How to implement the whole thing
Since your use case is pretty particular, you may encounter some resistance from existing software. But creating your own multitenant solution is not that hard