my logic is : 1. the /editor001/ , or call protect area, must required being auth. if auth succeed, it will give an captcha_auth, which has a backup in the redis for verify. if no auth, auth faile, or captcha_auth id don't have a backup in the redis, redirect to the /captcha_html.html 2. /captcha_check take care of a cookie analyze and try to find the captcha_auth id and compare to the redis, if yes, 200 and no-cache, no-store. 3. /captcha_html.html is a static html, 3.1 it will call /captcha_png to gen a PNG, which contain an image auth_code. and gen a captcha_session cookie for the client. and it will storage the auth_code / captcha_session pair to the redis. 3.2, if user type in a sumited-auth_code, and click submit button, the html submit data to the /captcha_auth 3.3 /captcha_auth analyze the cookie and try to find the captcha_session and auth_code , then try to maching with the auth_code / captcha_session in the redis. if "no", reject, and increase the failed counter. if "yes", delete the failed counter, generate a captcha_auth cookie, and storage a copy to the redis. 4. then, return to haproxy : 4.1, if client coming, and has the captcha_auth, it can not seen it as pass auth, 4.2, haproxy , must ask /captcha_check to help to detect whether the client hold a valid captcha_auth-cookie which has a copy in the redis. or, haproxy, can use the lua to check the redis directly.