Htmx and url_signer.verify() mobile browser

103 views
Skip to first unread message

Jacinto Parga

unread,
Aug 23, 2022, 12:27:01 PM8/23/22
to py4web
Hello, 

I get 403 error with htmx and url_signer.verify() in this context:
  • mobile browser (chrome or firefox), open  a page that is url_signed requests content with htmx (selecting something with radio button for example)
  • First time open the page everything works fine
  • But when I leave the browser app with the page still open and come back later the htmx POST content requested don't load due to a 403 error
  • If the page is reloaded everything works again
  • If I remove url_singer.verify() everything works fine

You can try this behaviour in this mock https://atletismomaster.es/mastercalc

Jim Steil

unread,
Aug 23, 2022, 1:07:13 PM8/23/22
to py4web
Have you tried posting on StackOverflow for htmx?  Or, they have a very active Discord server as well -> https://discord.com/invite/Z6gPqAd

-Jim

Alexander Beskopilny

unread,
Aug 23, 2022, 2:05:46 PM8/23/22
to py4web
I also noticed the incomprehensible behavior of url_signer
sometimes url_signer starts working normally if you replace

@action.uses(url_signer.verify(), session)
with
@action.uses(url_signer, session)

( I didn't use htmx )

Jim Steil

unread,
Aug 23, 2022, 2:35:58 PM8/23/22
to py4web
I have to admin I haven't used url_signer...

I have some learning to do.

-Jim

Jacinto Parga

unread,
Aug 24, 2022, 3:51:36 AM8/24/22
to py4web
Yes, if I replace url_signer.verify() with url_signer it seems to work, but the url sign is not verified

When the main page (the one from the htmx requests are made) is reloaded everything works.

The 403 error rises when a restored session is used in browser, so the url sing cannot be verified. I don't know how to prevent this behaviour or even if it should be prevented.

I like the concept of singning urls because it provides a safer information interchange. I wonder if url_signer allows to declare a specific session independent key for singing url's to be used in these situations.

Alexander Beskopilny

unread,
Aug 24, 2022, 4:54:34 AM8/24/22
to py4web

the url_signer seems to be working

https://github.com/ali96343/lvsio/blob/main/fgrid/g2/__init__.py
https://github.com/ali96343/lvsio/blob/main/fgrid/t1/__init__.py

( I connected grid.js and tabulator.js  to py4web-app )

Jacinto Parga

unread,
Aug 24, 2022, 5:11:51 AM8/24/22
to py4web
ok so the url sing is verified.

When I have a controller that is called by others and calls others with url_signer, I use this:

url_signer = URLSigner(session)
...
@action.uses("insertar.html", db, session, auth, T, Inject(T=T), url_signer, url_signer.verify() )

So I notice it would be enough:
@action.uses("insertar.html", db, session, auth, T, Inject(T=T), url_signer )

And the url signature will be verified.

Jacinto Parga

unread,
Aug 24, 2022, 5:30:45 AM8/24/22
to py4web
I have made a simple verification, changing the sign of the url and it rises a 403 error when url_signer.verify() is used but any url is valid if it is replaced by url_singer . So I don't think it really verifies if the url is correct.

Jacinto Parga

unread,
Aug 24, 2022, 5:37:27 AM8/24/22
to py4web
I think the question is how session is used by url_signer. If I use:

url_signer = URLSigner()

Then this error rises:

Traceback (most recent call last): 
 File "/home/xx/py4web3104/lib/python3.10/site-packages/py4web/core.py", line 934, in wrapper ret = func(*func_args, **func_kwargs) 
 File "/home/xx/py4web3104/lib/python3.10/site-packages/py4web/core.py", line 919, in wrapper raise context["exception"] 
 File "/home/xx/py4web3104/lib/python3.10/site-packages/py4web/core.py", line 896, in wrapper call(fixture.on_request, context)
 File "/home/xx/py4web3104/lib/python3.10/site-packages/py4web/core.py", line 881, in call return f(context)
 File "/home/xx/py4web3104/lib/python3.10/site-packages/py4web/utils/url_signer.py", line 124, in on_request print("on_request", self.session.get("_signature_key")) 
AttributeError: 'NoneType' object has no attribute 'get'

It would be great to sign url with any pre selected key

Jacinto Parga

unread,
Aug 24, 2022, 10:57:30 AM8/24/22
to py4web
Yes, may be it is solved. 

The line 124 in url_signer.py

print("on_request", self.session.get("_signature_key"))

It raises an error when the session paramenter is not inlcuded in URLsigner. So it is no posible to declare 

url_signer = URLSigner()  

or put a key parameter. 

I guess the line 124 is for debugging reasons, and should be eliminated for production.

Then it is possilbe to make url_signer session independent, so the nasty effect in restored sessions is avoided.

Alexander Beskopilny

unread,
Aug 24, 2022, 11:31:19 AM8/24/22
to py4web
line 75 says:
Signer for URLs.

:param session: Session. If a session is not specified, it will use a key
to sign the URLs.
-----------------------------------------

I use both constructs
url_signer = URLSigner(session, lifespan=3600)

url2_signer = URLSigner(lifespan=3600)

Jacinto Parga

unread,
Aug 24, 2022, 1:45:17 PM8/24/22
to py4web
You don't get error with url2_signer due to line 124?

print("on_request", self.session.get("_signature_key"))

Alexander Beskopilny

unread,
Aug 24, 2022, 2:29:13 PM8/24/22
to py4web
no I'm not getting an error
here's the output

app https://github.com/ali96343/lvsio/tree/main/fgrid


[X] loaded _documentation
Ombott v0.0.14 server starting up (using <class 'py4web.server_adapters.wsgirefThreadingServer.<locals>.WSGIRefThreadingServer'>(reloader=False))...
Listening on http://127.0.0.1:8000/
Hit Ctrl-C to quit.

on_request None
on_request e46d3d0c-23d9-11ed-9b2a-b62eee75cba2
on_request e46d3d0c-23d9-11ed-9b2a-b62eee75cba2
on_request e46d3d0c-23d9-11ed-9b2a-b62eee75cba2

wsgiref.log

ThreadPoolExecutor-0_0 | 127.0.0.1 - - [24/Aug/2022 21:23:59] "GET /fgrid/g2/editable_table HTTP/1.1" 200 4578
ThreadPoolExecutor-0_0 | 127.0.0.1 - - [24/Aug/2022 21:23:59] "GET /fgrid/g2/api_editable/data?_signature=7B227473223A2022313636313336353433392E313631222C202273616C74223A202265626630326631632D323364392D313165642D396232612D623632656565373563626132222C2022736967223A202243414238394234383637414145314541314632393838454235373842413036333837304138363933393834303131383239384237423230373432344443444132227D&sort=&start=0&length=10 HTTP/1.1" 200 1752
ThreadPoolExecutor-0_0 | 127.0.0.1 - - [24/Aug/2022 21:23:59] "GET /favicon.ico HTTP/1.1" 404 461

Alexander Beskopilny

unread,
Aug 24, 2022, 2:58:39 PM8/24/22
to py4web
you can check the operation of the url_signer

1 controller /fgrid/g1/api_editable/data is not protected
set7-py39) [w3p@sun py4web]$ http http://localhost:8000//fgrid/g1/api_editable/data
HTTP/1.0 200 OK
Content-Length: 17350
Content-Type: application/json
Date: Wed, 24 Aug 2022 18:48:19 GMT
Server: WSGIServer/0.2 CPython/3.9.12

{
    "data": [
        {
            "address": "3956 Bailsssssey Loaf Suite 582, North Jasmine, IN 03748iiiiiiiiiii",
            "age": 74999,
            "email": "anthony...@example.com",
            "id": 89,
            "name": "Aaxxxxrrrrrrrxxxxxxxxxxvvvxccccccxxxiacccc",
            "phone": "649-593-86666026x2918"
        },
........

2 controller /fgrid/g2/api_editable/data -  protected

(set7-py39) [w3p@sun py4web]$ http http://localhost:8000//fgrid/g2/api_editable/data
HTTP/1.0 403 Forbidden
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Wed, 24 Aug 2022 18:52:54 GMT
Server: WSGIServer/0.2 CPython/3.9.12
Set-Cookie: fgrid_session="v1-hmac256:b4a9299041c3bfce8651a9f4b8a1c03f700d64198333ebf7536195d007e0b08e:38Zd6OG1mPdweZ-6chz1CPNGyd9gT8FulbSvVLcYa1GallSJgNYDN5Rz1Wqgkpoo8Xf0lXvkzyB1-T1_zFG1qIuocs_NsmihJ5JEnlch62pkYXYDvvuYv1ZjVO0MEvFPTdAs0kN20gNouSXYb0HnKwyeRixcrI3dcpDszijLNkds81EdgLTO5Zr5BaJkTIDmMXu8fwTkvmHT3jILQr-c1CWhO6VMQ213UMaYVJ_MILk="; Path=/; SameSite=Lax

the url_signer works as expected
(  url_signer  is very cool and useful for protecting interfaces )

Jacinto Parga

unread,
Aug 25, 2022, 3:47:03 AM8/25/22
to py4web
Hi again, 

Yes you're right. I'm using the py4web 1.20220807.1 installed from pip. In this version url_singer.py has a print line (124) that makes url_signer.verify() fail. I don't know if you are using this version or the previous without that specific line.

Alexander Beskopilny

unread,
Aug 25, 2022, 7:50:30 AM8/25/22
to py4web
Hello!

I use:
py4web  __version__ = "1.20220725.2" from github
line 124 from py4web/utils/url_signer.py

  print("on_request", self.session.get("_signature_key"))

(also, for historical reasons, I use the wsgiref server in my applications)
-----------------------------------------------------------------------------------

I will explain why I use the url2_signer = URLSigner(lifespan=3600, )

The left_menu.py file uses a URL, a function outside the controller,
and if I tried to make a signature using  url_signer = URLSigner(session, lifespan=3600,) ,
I received messages something like "context error   .... outside context .... etc"

(this signature  ( url2_signer = URLSigner(lifespan=3600,  )
doesn't make much sense, I just wanted to see how the signature works without a session)

about y4web/utils/url_signer.py
I looked at this file for a long time and my signature did not work ....
then suddenly everything took and worked
after I started using lines

@action.uses(url_signer.verify())
@action.uses(url_signer, session)
Reply all
Reply to author
Forward
0 new messages