为什么已经登录的用户点一个没权限的页面,会被送回登录页?装饰器和 Mixin 的行为为什么不一样?这篇把每种情形的响应码和 Location 都列出来。
GET /secret/ → 302 Location: /accounts/login/?next=/secret/ GET /cbv/ → 302 Location: /accounts/login/?next=/cbv/ GET /perm-redirect/ → 302 Location: /accounts/login/?next=/perm-redirect/ GET /perm-403/ → 403 GET /staff/ → 302 Location: /nostaff/?next=/staff/ GET /secret/?x=1&y=2 → 302 Location: /accounts/login/?next=/secret/%3Fx%3D1%26y%3D2
LOGIN_URL 决定去哪里登录(本实验设为 /accounts/login/)。
GET /secret/ → 200 GET /perm-redirect/ → 302 Location: /accounts/login/?next=/perm-redirect/ GET /perm-403/ → 403 GET /pcbv/ → 403 GET /staff/ → 302 Location: /nostaff/?next=/staff/
装饰器版本默认重定向,是因为它把「没权限」当成「换个账号试试」。对已经登录的用户这几乎总是错的——用 raise_exception=True,或自己抛 PermissionDenied。
GET /secret/ → 200
GET /perm-redirect/ → 200
GET /perm-403/ → 200
GET /pcbv/ → 200
GET /staff/ → 200
follow=True 之后落在: [('/accounts/login/?next=/secret/%3Fx%3D1%26y%3D2', 302)] login page next=/secret/?x=1&y=2一切正常。
/dashboard/ → 允许跳转: True //evil.com/ → 允许跳转: False https://evil.com/x → 允许跳转: False https://testserver/x → 允许跳转: True javascript:alert(1) → 允许跳转: False
开放重定向是钓鱼的常用手段:把 next 指到外部站点。