Null captcha — invalid frontend token
Overview
On a feedback page no captcha shown and the error is occured:
null captcha — invalid frontend token: 0x8d40af589c1a9838cf365c3341bd542347bbd4ebbd95255fff5b592f19a12cc33d5ab564d4abff85f533f9e5ce7db5a0, backend report: /captcha/?%c2%18%24%82%47%9e%3f%ee%c2%9e%73%61%ac%eb%87%bc%fe%73%2d%bb%29%74%2c%e5%09%9c%17%cc%08%02%85%4a is fetched via Pheix::Controller::API.captcha: 0xef89f4a06b42d755664c553d2af9ae8d31535b2eef779b9a24c8df7dfbf3b1daa3f33f32f14fb37c410c1c6f1632(0x8d40af589c1a9838cf365c3341bd542347bbd4ebbd95255fff5b592f19a12cc33d5ab564d4abff85f533f9e5ce7db5a0)
Investigation
FastCGI
By default 3 FastCGI workers are up and running on server. This is configured by FcgidMinProcessesPerClass directive:
kostas@ala-archa:~$ ps ax | grep pheix.raku
703269 ? Sl 20:41 raku /home/kostas/nvme/home/apache_root/pheix.org/www/pheix.raku
703386 ? Sl 21:37 raku /home/kostas/nvme/home/apache_root/pheix.org/www/pheix.raku
703403 ? Sl 19:51 raku /home/kostas/nvme/home/apache_root/pheix.org/www/pheix.raku
1117404 pts/2 S+ 0:00 grep --color=auto pheix.raku
Each worker runs instance of Pheix dCMS. At metrics implementation I added names to instances, so on dashboard we see:
Invalid session token
Fronted token is created on Pheix instance start and is stored at pageobj of controller's %!sharedobj attribute.
Obviously, there are 3 different session tokens cause of 3 independent instances of Pheix (workers) run by fcgi_mod. Apache's fcgi_mod is switching between workers according built-in policy (I guess basically for load balancing reasons). So at some moment (moment of workers switching) request with session token issued by worker X reaches the worker Y and that causes the null captcha — invalid frontend token error.
Fix proposal
- Session token is created by backend on page render, best format: 64 bytes hex value from
random(64); - Session token stored in local database on creation with
createdandmodifiedmetadata field populated withnow()value; - Since session token is created, saved to database and sent to client within the requested page;
- Until page is reloaded, frontend will send this session token only, so we can check it in database for existence and expiration.
General question: how can we efficiently update or expire the session?
Update or expire the session
If session token is expired (modified - created > some delta value):
- Change token's status to
expired; - Generate new token on the fly and return it to frontend as a
sessiontokenin API response.


