特定场景下Django认证流程的运行逻辑是什么?
Django 认证流程逻辑解答
基础前提:Django URL匹配核心规则
- 按
urlpatterns的书写顺序从上到下匹配,若规则是include子路由,会先将前缀匹配成功的剩余路径传入子路由匹配,若子路由无匹配项,会回到根路由继续匹配下一条规则 include("xxx.urls")的作用是将当前路径作为前缀,和子路由文件里的路径拼接后完成全路径匹配
疑问1:path("", include("app.urls"))的匹配场景和原因
- 匹配场景:当请求路径不是
admin/开头,且不属于authentication应用下的三个路径(login/、register/、logout/)时,就会匹配到这条规则 - 原因:根路由第一条匹配
admin/的规则不命中后,会先尝试匹配第二条path("", include("authentication.urls")),空前缀可以匹配所有路径,但authentication的子路由仅配置了三个路径,请求路径不在这三个范围内时,子路由匹配失败,就会回到根路由继续向下匹配,命中第三条空前缀的app.urls规则
疑问2:匹配path("", include("authentication.urls"))时,login/路径的来源
login/是用户请求的完整路径的一部分,通常有两种触发场景:- 用户手动访问
http://localhost:8000/login/ - 未登录用户访问需要权限的页面时,Django的
@login_required装饰器自动重定向到/login/地址
- 用户手动访问
- 路径匹配逻辑:请求路径
/login/匹配到根路由的空前缀"",剩余路径login/传入authentication的子路由,刚好匹配到子路由中path('login/', login_view, name="login")的规则,因此由login_view处理请求
疑问3:login_view重定向到/不会产生循环的原因
循环不会触发有两个核心原因:
- 空路径
/不会匹配authentication应用的任何子路由:authentication的子路由没有配置对应空路径的规则,因此访问/时,第二条根路由匹配失败,会直接走第三条app.urls的规则,不会进入认证相关的视图逻辑 - 认证状态的校验:
app应用下对应/路径的视图,通常会加@login_required装饰器,用户登录成功后,装饰器检测到当前请求已经处于登录状态,会直接返回页面内容,不会再重定向到/login/,因此不会产生循环
完整认证运行流程
我们以未登录用户访问首页/的完整流程为例:
- 未登录用户发起
GET /请求 - 根路由先尝试匹配
admin/规则失败,再尝试匹配authentication的子路由,子路由中没有对应空路径的规则,匹配失败,最终命中app.urls的首页规则 - 首页视图的
@login_required装饰器检测到用户未登录,自动重定向到/login/地址 - 发起
GET /login/请求,匹配authentication子路由的login/规则,login_view返回登录表单页面 - 用户填写账号密码提交
POST /login/请求,login_view校验表单通过后调用authenticate方法验证账号密码,验证成功后调用login方法写入登录态Session,重定向到/ - 再次发起
GET /请求,app的首页视图检测到用户已登录,正常返回首页内容,流程结束
内容的提问来源于stack exchange,提问作者a298b112
相关产品推荐
相关产品推荐

