I am working to convert example code from Flask to twisted. The flask program is storing data in a session like so:
session['samlUserdata'] = self.auth.get_attributes()
session['samlNameId'] = self.auth.get_nameid()
session['samlSessionIndex'] = self.auth.get_session_index()
session['samlExpiration'] = datetime.now() + timedelta(minutes=SESSION_LENGTH)
In this case session is a flask global, but I want to accomplish the same thing in twisted. Basically I want to store values in my session so I can use that data in other requests.
I know I can access the session data in request.getSession() and have seen some examples of counters but the idea is not translating to what I am trying to do.
Can anyone explain how I would set and retrieve data in a twisted session? As I have said I have seen the counter example and need a more concrete example of how this would be done.
Thanks!
Twisted's session code was conceived long ago and a lot has changed in the web server landscape. I'm not sure if this is the "optimal way" of doing it but you can store session info in a cookie using JWT. Here's an example using klein
import uuid
from klein import Klein
import jwt
router = Klein()
#router.route('/jwt')
def cookie_magic(request):
# set cookie if none
if request.getCookie(b'session_token') is None:
session_id = uuid.uuid4().hex
session_token = jwt.encode({'foo': session_id}, '#TODO Secret', algorithm='HS256')
request.addCookie(b'session_token', session_token)
return 'session_id set to {0}'.format(session_id)
# get the cookie
session_token = jwt.decode(request.getCookie(b'session_token'), '#TODO Secret', algorithm='HS256')
return 'hello {0}'.format(session_token['foo'])
router.run('0.0.0.0', 7777)
This allows you to be more flexible in terms of sessions. For instance if you have another non-twisted web app, you can easily get the session token from the cookie.
Related
I am using Flask and SqlAlchemy, the case is that I have a main database and then I have several databases where I get other information. But the credentials are not defined as fixed, so I have to obtain them from a table in the main database, depending on the plant where the user is. For this I use SQLALCHEMY_BINDS. the problem is that when I try to pass the connection string to the Bind I told myself that the function that returns it is out of context. Here a portion of the code
def scadaConnect():
idplanta_session=str(session['idPlanta'])
usernamequery = db.session.query(Scada.usernameScada).filter(Scada.idPlanta=='5')
hostquery = db.session.query(Scada.hostScada).filter(Scada.idPlanta=='5')
passwordquery = db.session.query(Scada.passScada).filter(Scada.idPlanta=='5')
nombredbquery = db.session.query(Scada.nombrebdScada).filter(Scada.idPlanta=='5')
nombredb = str(nombredbquery[0])[2:len(nombredbquery[0])-4]
host = str(hostquery[0])[2:len(hostquery[0])-4]
password = str(passwordquery[0])[2:len(passwordquery[0])-4]
username = str(usernamequery[0])[2:len(usernamequery[0])-4]
connexion = 'mysql+pymysql://'+username+":"+password+"#"+host+"/"+nombredb+"'"
def retorno():
return str(connexion)
from config import SQLALCHEMY_BINDS
SQLALCHEMY_BINDS['scada']= scadaConnect()
The error is as follows
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem.
session (first line in scadaConnect()) is only available in a request context a.k.a. view. It lives in the session cookie on the client and is sent to the server (and available to your view) only when the browser makes a request.
You will have to move the call to scadaConnect() to a view if you want to use session.
So, here is my problem, I want to test the blind SQL injection based on boolean, which is a login form, I judge the correctness by the length of the response message, but after I logged in, the cookie is saved, and I'll always be logged in, I just want to delete the cookie which is stored by python 3, can anyone give me an suggestion.
Here is my code
import requests
url="https://www.example.com/admin"
params={
"login":" or ((select user()) LIKE 'a%')#",
"passwd":"xxxxxx"
}
html=requests.post(url,data=params)
print(len(html.text))
I want to make bokeh embedded web app.
resources said "autoload_server" works but it does not.
session=pull_session(url=url,app_path="/random_generator")
bokeh_script=autoload_server(None,app_path="/random_generator",session_id=session.id, url=url)
I think autoload_server can not be used anymore
so instead of this, I want to use server_document
I wrote this code but still does not work
how should I write this code?
session=pull_session(url=url,app_path="/random_generator")
bokeh_script=server_document("/random_generator")
server_document is for creating and embedding new sessions from a Bokeh server. It is not useful for interacting with already existing sessions, i.e. it is not useful together with pull_session. For that, you want to use server_session, as described in the documentation. For example, in a Flask app you would have something like:
#app.route('/', methods=['GET'])
def bkapp_page():
with pull_session(url="http://localhost:5006/sliders") as session:
# update or customize that session
session.document.roots[0].children[1].title.text = "Special Sliders!"
# generate a script to load the customized session
script = server_session(session_id=session.id,
url='http://localhost:5006/sliders')
# use the script in the rendered page
return render_template("embed.html", script=script, template="Flask")
In my website I have a user panel which displays info about user (or a custom message if he is not logged in). I'd like to know how can I do that a user object is accessible within every template? (like Django's CONTEXT_PROCESSORS).
I know I can add_request_method() to my config object but as far as I understand it will only make user's object available in request but I will have to add it to returned context manually each time - not good.
Maybe I should add user's object to session?
What is the proper way to do it?
What you need in Pyramid is an authentication policy. This can be as simple as adding these lines to your __init__.py:
from pyramid.authentication import AuthTktAuthenticationPolicy
def main(global_config, **settings):
...
authentication_policy = AuthTktAuthenticationPolicy('some_key')
config = Configurator(settings=settings,
authentication_policy=authentication_policy)
...
Once an authentication policy is in place, you can use the 'forget' and 'remember' functions from pyramid.security to allow users to log in and out. Here's a simplified view function that handles logins:
from pyramid.security import remember, forget
def sign_in(request):
username = request.POST.get('username')
password = request.POST.get('password')
if username and User.verify_password(username, password):
headers = remember(request, username)
else:
headers = forget(request)
return HTTPFound(location=request.route_url('index'),
headers=headers)
There are a few things you'll have to change there - maybe your User object doesn't have a 'verify_password' method; maybe you want to redirect to a different page on successful login, etc. But it's something to get started with.
Then in my base template I can add:
<%
from pyramid.security import authenticated_userid
user_id = authenticated_userid(request)
%>
to make the user_id available for use in the template and then:
% if user_id:
<p>Welcome ${user_id}</p>
% else:
<p>Please login here</p>
% endif
Note I'm using Mako syntax - if you're using a different templating engine you should check their syntax for imports, conditionals, etc.
I've given a basic outline of the different pieces and how they slot together, but Pyramid has powerful authentication features, and I encourage you to read a little about how it works:
The Pyramid documentation: http://docs.pylonsproject.org/projects/pyramid/en/latest/api/authentication.html
This excellent demo of Pyramid's authentication policies:
https://github.com/mmerickel/pyramid_auth_demo
I know you already mentioned the add_request_method() solution, but that's what I ended up with after following this tutorial on adding a user object to the request.
I might not be doing anything that out there with my pyramid apps, but basically every view and template I have has a request object as part of it, so within any template I can do <% request.user %> and have my user object and everything part of that available. I even have some helper methods and relationships that just come through and are available automagically as request.user.
What example case do you have where the request object isn't available?
Using node.js with Express. This question also pertains to Connect since that's the Express sub-component in question.
I receive a signed cookie from the client over socket.io. Then I take the value of it which is in this format:
s:sessionID.signature
Currently to validate this I had to manually require the cookie-signature module and use its unsign method, which requires me to .slice(2) the s: off of this string, and just feels kludgy.
Is there a convenience method for this? I feel like I ought to be able to just do something like:
mySessionID = express.unsignCookie(thisCookie, forThisSessionIDKey, withThisSecret);
But no such method exists... am I missing something?
Oh, BTW, I can't access res/req due to being in socket.io... Which is why I'm having to pass the session ID over from the client's cookie in the first place...
Here was the solution I ultimately found. Inside socket.js:
var parseSignedCookie = connect.utils.parseSignedCookie;
...
socket.on('taste:cookie', function (data, callback) {
var sid = data.sid;
sid = parseSignedCookie(sid['connect.sid'], "mySecret");