How to check two Session are the same? - python

I have written a program by Python. I am using the requests library and want to set the Session.
I have tried to create a function for the network request,the arguments is url(str) and session object. (I have used the session for request a website)
The problem is: The session is not fixed (just my opinion). When I put the session argument to the function, the request will return the wrong page, but when I haven't use the function (I have use the threads with the function), I request another website with the session after the first request, the returned page is right. So I think the problem is the Session object is not the same in function's local Session and global Session, I want to check the sessions if same, how to do it?
My Mother tongue is not English, so the English is not good,please excuse.
code:
import requests
from tomorrow import threads
# create a session
s = requests.Session()
# the right code
# s.post(url1)
# s.get(url2)
# the wrong code
#threads(100) # create threads
def request(url, session):
return session.get(url)
s.get(url1)
req = request(url2, s) # that will return a wrong page

Related

Cookie is not created when calling the endpoint in FastAPI

I have encountered an issue, as I have to create a cookie in the backend, which I will later use to send a request from the frontend. Both apps are on the same domain. This is the general idea behind it: https://levelup.gitconnected.com/secure-frontend-authorization-67ae11953723.
Frontend - Sending GET request to Backend
#app.get('/')
async def homepage(request: Request, response_class=HTMLResponse):
keycloak_code = 'sksdkssdk'
data = {'code': keycloak_code}
url_post = 'http://127.0.0.1:8002/keycloak_code'
post_token=requests.get(url=url_post, json = data )
return 'Sent'
if __name__ == '__main__':
uvicorn.run(app, host='local.me.me', port=7999,debug=True)
Backend
#app.get("/keycloak_code")
def get_tokens(response: Response, data: dict):
code = data['code']
print(code)
....
requests.get(url='http://local.me.me:8002/set')
return True
#app.get("/set")
async def createcookie(response: Response):
r=response.set_cookie(key='tokic3', value='helloworld', httponly=True)
return True
if __name__ == '__main__':
uvicorn.run(app, host='local.me.me', port=8002, log_level="debug")
When I open the browser and access http://local.me.me:8002/set, I can see that the cookie is created.
But when I make a GET request from my frontend to backend to the same URL, the request is received—as I can see in the terminal—but the backend does not create the cookie. Does anyone know what I might be doing wrong?
I have tried different implementations from FastAPI docs, but none has similar use cases.
127.0.0.1 and localhost (or local.me.me in your case) are two different domains (and origins). Hence, when making a request you need to use the same domain you used for creating the cookie. For example, if the cookie was created for local.me.me domain, then you should use that domain when sending the request. See related posts here, as well as here and here.
You also seem to have a second FastAPI app (listenning on a different port) acting as your frontend (as you say). If that's what you are trying to do, you would need to use Session Objects in Python requests module, or preferably, use a Client instance from httpx library, in order to persist cookies across requests. The advantage of httpx is that it offers an asynchronous API as well, using the httpx.AsyncClient(). You can find more details and examples in this answer, as well as here and here.

Capturing variable returned by API in Flask

I'm trying to capture a variable generated by Flask after visiting a certain URL.
I want to use that variable in further authorization in the API.
Due to the nature of Flask, every time the user visits the web app's URL, a function is called that returns a variable.
I want to capture that variable and use it further, without executing the function (the function should be executed only once).
Here's the code I have:
#app.route("/callback/")
def callback_code():
auth_code = request.args.get('code')
return auth_code
code = callback_code()
tracks_endpoint = "https://api.spotify.com/v1/me/tracks"
tracks_auth = {
"Authorization":f"Bearer {code}"
}
tracks = requests.get(tracks_endpoint, headers=tracks_auth)
The problem is caused by:
code = callback_code()
After visiting http://127.0.0.1:5000/auth, Flask displays the following error:
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.
How can I capture auth_code and store it, without executing the function?
Thanks for all your help!
So first problem is that you're expecting the server to be running and get some callback, but the code that is not intended in a function is going to be immeadiately ran, externally from the Flask server lifecycle.
Best way I can think to handle that would be to have your callback redirect to another endpoint, and save off your auth token somewhere in between (such as a session cookie)
Or using a separate variable, for example
AUTH = {
'spotify': None
}
tracks_endpoint = "https://api.spotify.com/v1/me/tracks"
#app.route("/callback/")
def callback_code():
auth_code = request.args.get('code')
AUTH['spotify'] = auth_code
return redirect(url_for('tracks'))
#app.route("/tracks")
def tracks():
if not AUTH['spotify']:
raise('Auth code not loaded. Login first')
tracks_auth = {
"Authorization":f"Bearer AUTH['spotify']"
}
tracks = requests.get(tracks_endpoint, headers=tracks_auth)

Flask Blueprint Putting something on session

I was trying to put
session['logged_in'] = True
in the session, but in another blueprint it doesn't persist... Why is that?
Is there any better way to keep something in the session?
Extended:
I have a blueprint giving a form to login. When done and submitted, it will set a session key like above. Then it redirects via
return redirect(url_for('admin.index'))
to admin page where If I call the key via
session.get('logged_in')
I get "None" Instead of the True or False one.
I think I understand your confusion now~
Your flask session won't store anything on the server.
the 'session' dict is filled by the cookies from the client request.
Again. that is:
client make login request to server, and got a [login success] response as well as a [cookies] which contains the !!!sessionINFO!!! you think are stored on the server side.
Next time, you must send the whole cookies to the server again, then your session in the server may have data.
Browser will do this for you.
If you use a local client, say python requests library. Then be sure you are making requests with session (for requests-lib, it's requests.Session())
------------------OLD-------------------------------------
Though not an expert, but the case you described should not have happened.
The session is cookies data encrypted with a secret, if you have gone through the document mentioned by Beqa.
Just set
app.secret = '........'
And use session as a dict.
just FYI,
client request---->server (encrypt your_data 'logged_in' and client_relating_data 'maybe: ip, host or etc.', and put the encrypted info in cookies 'session=....') ------> client (get response with cookies)
client request again -----> server (decrypt the cookie 'session=...' with your secret), find the 'logged_in' data and know you are logged in.)
the cookies is something like below.
So, I'm not sure what's actually your trouble when using session, and put some basic information here. Just hope it helps in case.

In flask, how to route a link generated by OAuth 2?

I'm building a web app with flask. I used
#app.route('/')
def home():
.....
return render_template('home.html',url=url)
to generate the index page. There is a link(the second parameter, url) on the index page which leads to weibo (the chinese "twitter") for OAuth 2. After clicking the link and inputing the weibo username and password, I'm bounced back to a link like www.myflaskwebappaddress.com/?code=valueofcode.
My question is how can I catch the value of code and do something with the code in another page.
I tried the following:
#app.route(url_for('/', code=<tokencode>))
def show_data(tokencode):
.....want to use weibo api here using the tokencode.
But it doesn't work.
Everything after the ? is a query parameter; Flask parses those and provides them as part of the request.args object:
#app.route(url_for('/')
def home():
tokencode = request.args.get('code')
if tokencode is not None:
# there was a `?code=...` query parameter.
Also see The Request Object in the Flask quickstart.
Routing is only dependent on the path and the method of the request, the parameters don't play in that, so you cannot create a separate route for requests with that parameter.
You could, instead, use a before_request handler to look out for the code:
#app.before_request
def check_token():
tokencode = request.args.get('code')
if tokencode is not None:
# there was a `?code=...` query parameter.
If this function returns None, the normal routing takes place. But you can also return valid response; in that case that is the response returned to the end user and normal routing is skipped entirely.
This also means you can use any route on your site with a ?code=<tokencode> query parameter and have the before_request hook function handle it, not just your homepage.

Cookie Storage on Google App Engine

Extreme newbie, apologize in advance, I have no idea what I'm doing -- but I really have looked around.
I am downloading a few dozen pages behind a login form and dbing the results, running on GAE. I would like to enqueue each page read and database write in the task queue. When I changed over to task queue, I realized I had problems passing my session around.
I create an opener using urllib2:
cj = cookielib.CookieJar()
session = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
session.addheaders.append(('User-agent', 'Mozilla/4.0'))
login_data = urllib.urlencode({ 'username' : 'guest',
'password' : 'guest',
'Submit1' : 'Submit'})
resp = session.open(self.login_page, login_data, timeout=20)
self.session = session
Previously I was only instantiating this class once at the head end of things, creating one session instance variable for everyone to use, and then passing my instantiation around to keep context. Using task queue I cannot pass objects, so when my request handler gets called, I can't give him reference to the opener or the cookie.
Is there a way to store or pass the opener, or the cookie info so that I can build a new opener without logging in again each time? Can I pass cookie information through the headers dictionary to each handler? Stuff something in memcache? What exactly do I need to pass to get the cookie back into a valid opener?
Many thanks to anyone who wades through the above.
You can pass objects via deferred library instead of taskqueue.
But for reliability reason, I recommand you to store your objects in datastore and only pass there reference in taskqueue.

Categories