Is Flask-Session logic similar to JWT - python

I have a question about flasks session logic. First of all as I know there are two ways to store session data, one is on client side and the second is server side. Flask, as I know, is using the former one (client side) where the session is encrypted and stored on the browser of the client.
Let's us say we want to make a login on a flask-backend
User does a login, flask generates a session and through set-cookie the client stores the session
User makes another request to the backend and sends its cookies where also the session is stored and flask validates the session with the key which it used to encrypt the session
When the session is valid, flask loads the session, thus that means the user is logged in
And JWT works the following as I know. It generates a token and the client stores the token and sends it in each request to the server, where the token is validated.
As I know, both flask and JWT uses a secret to encrypt the data.
So can we say, that flask-session and JWT are somehow similar?

Both jwt and flask session work on client, but the key difference is that flask session stores the signed session data at the client cookie, but in jwt you have the independence to store the token anywhere you want, say localstorage, cookie etc.
And jwt will be base64 encoded by default while in flask session it has to be done manually for security. But yes the difference between traditional sessions (say php) and flask-sessions is that the session data is stored in the client rather than as a file at the server (while the client cookie has session id in traditional sessions).

Related

Using Azure AD to authenticate react application and backend application(python)

I am able to authenticate the react app with AAD and I am able to get the access token.
I have the following questions:
My backend is in python flask (WEB API's). How do I make sure that every request sent by react app is also authenticated with the same token?
Should I register a different application for the backend( python flask) or I can use the client ID of the same frontend application?
If I am passing the token in the header while calling every API request from the frontend, how backend will verify is the token is valid? Also, should it verify every API request?
I have seen multiple options like flask-azure-oauth library and some other libraries. For frontend I have tried ADAL and MSAL libraries.
In frontend make sure you append the accessToken in you're each HTTP request like, writing a common HTTP module and use it across the react app. And to make sure you're app is authenticated with same token you need to wrap react app with adal or MSAL or react-adal.
You have to use the same client id which used in react app in you're python backend in-order to verify the token you're sending in the API request.
You need to add before_request hook in flask and verify the accessToken you receive in the request. reference link
you can also check react-adal package for AAD authentication.

SESSION_COOKIE_SECURE does not encrypt session

I'm trying to put some security on my Flask web app. As a first step I'm going to make my session cookie secure by setting SESSION_COOKIE_SECURE to true.
But after I get my session cookie from "inspect element" I can decode session cookie easily and there is no difference whether I add SESSION_COOKIE_SECURE or not.
Here is my code:
from flask import Flask, request, app, render_template, session, send_file, redirect
MyApp = Flask(__name__)
MyApp.secret_key = "something"
application = MyApp
if __name__ == "__main__":
MyApp.debug = False
MyApp.config.update(
SESSION_COOKIE_SECURE=True,
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE='Lax',
)
MyApp.config["SESSION_PERMANENT"] = True
MyApp.run()
I also tried to add this attribute using the following syntax but this made no difference:
MyApp.config['SESSION_COOKIE_SECURE'] = True
When I try to print SESSION_COOKIE_SECURE I get this error
Traceback (most recent call last):
File "...", line ..., in <module>
print(MyApp.session_cookie_secure)
AttributeError: 'Flask' object has no attribute 'session_cookie_secure'
My Flask version is 1.0.2, and I'm on HTTPS.
Setting SESSION_COOKIE_SECURE does not encrypt the cookie value, no. When set, this causes Flask to create cookies with the "Secure" flag set. This means that a browser can only return the cookie to the server over an encrypted connection, nothing more. The setting doesn't change anything about the cookie value itself.
Flask produces cookies that are cryptographically signed, by default. That means that the cookie contents can be decoded but not altered, because a third party without access to the server secret can't create a valid signature for the cookie.
You generally don't need to encrypt your session cookie if you a) use HTTPS (which encrypts the data from outsiders) and b) protect your web app from XSS attacks. Without an XSS attack vector, attackers can't get access to your cookie contents at all anyway.
You certainly don't need to do so here, as SESSION_COOKIE_HTTPONLY means that the browser will never expose the cookie to JavaScript, and only someone with full access to the browser can see the cookie value.
Flask doesn't have a 'encrypt cookie' setting, because it is not deemed necessary when you can secure the cookie in other ways. You should not store information in a session cookie so sensitive that it should be protected from the end-user with access to the browser storage; keep such data on the server and only store a unique identifier in the session to retrieve that secret data later on.
If for some reason you can't keep such secrets out of the session cookie and are unwilling to accept that the end-user can read this data, then you'll have to encrypt the cookie yourself or use an alternative session provider for Flask, such as EncryptedSession.
As for the attribute error: only a few configuration settings are accessible as attributes on the Flask object. To print arbitrary configuration settings, use the app.config object:
print(MyApp.config['SESSION_COOKIE_SECURE'])

Sharing a SOAP client object between Django views

My Django application uses an API which is a SOAP service. I'm currently using a python SOAP/WSDL client called SUDS. In order to use the API, I have to initialize the client and provide it with a link to the endpoint, login, API key, and password.
Simplified code that does it:
from suds.client import Client
client = Client('link.to.WSDL.endpoint')
session_id = client.service.a_log_in_service('api_key', 'login', 'password')
# the session_id is required by all other 'client.service.xxx' services
Everything works just fine, although it takes some time to initialize the client.
Now, every time I want to send a request to the API in a view, I have to initialize the client. I can't see any way to "share" the already initialized client among many views. It would be great to have the client up and running somewhere, so that any user can send an API request using it.
Once I've done the log in in a view, I can store the session_id (in a session, db, file) and use it in other views, but the client still needs to be initialized over again, which means downloading the 200-KB XML file.
Having to download 200 KB every time a user hits a button seems not right at all.
Thanks in advance!

What to set Redirect URI for OAuth2 in Salesforce?

I'm using the following library for Salesforce OAuth Request: https://github.com/heroku/salesforce-oauth-request
I've created a Connected App, but have no idea what to set the redirect uri. Can I just set it to "https://www.google.com/"?
I just want to connect to Salesforce's Chatter API via python code, and don't care where the user gets directed as long as I get a refresh token from the oauth2 protocol

Flask-Login + Flask-Sockets = Chaos

I have installed Flask-Login and Flask-Sockets. Both of them work fine HOWEVER when I try to get the current user (using g.user), I get an AttributeError: '_AppCtxGlobals' object has no attribute 'user'
#sockets.route('/echo')
def echo_socket(ws):
with app.app_context():
user = current_user #This causes problems, just like basically anything else that uses something that is not provided in this function
while True:
message = ws.receive()
ws.send("lol")
I am still new with Flask, any help would be super appreciated.
The problem is that you are treating your socket functions as if they were regular requests, which they are not.
In a regular (i.e. non-socket) situation the client sends requests to the server. Each request contains a cookie that was set at login time by Flask-Login. This cookie contains the user that is logged in. Flask-Login has a before_request handler that reads this cookie, loads the user and then exposes it through current_user, so that by the time your function runs you have access to this information.
Socket connections are nothing like the above. For a socket connection the client opens a socket to a route and that establishes a permanent connection with the server. The concept of a request does not exist here, it's just two machines sending and receiving data using their own protocol. Because there are no HTTP requests there is also no cookies, no before_request handlers, no application and request contexts pushed and no current_user from Flask-Login. The socket routes really function outside of the Flask application.
If you need to know the user you will need to have the client send credentials through the socket interface, and you will need to authenticate those credentials in your socket route on your own, since Flask-Login cannot work in the socket environment due to the lack of requests, cookies, etc. A significant difference between sockets and regular routes is that the socket connection is permanent, so you only need to authenticate the user when the connection is established.
I hope this helps. Sorry I don't have a quick and easy solution for you.

Categories

Resources