React + Axios + Django前后端分离CSRF问题解决方案

想直接看代码的移步GitHub:

https://github.com/769484623/TestWebServer


CSRF 403 Forbidden这个问题从我刚开始做这个前端登录界面的时候就遇到了,但为了不耽误学习进度关闭了Django的CSRF验证选项。
现在快要做完了,就抽出了半天时间来解决了这个问题。
并不难其实,就是网上的资料有点不靠谱= =

Django的配置

额……虽然说是配置吧,但其实没什么说的……重点可能就是 @ensure_csrf_cookie 这个修饰符吧(一看到@我就想起来春招面试面试官问我修饰符的作用)。放个代码帮助理解下。

#url.py
urlpatterns = [
    path('Auth/', include('LoginAuth.urls')),
    path('admin/', admin.site.urls),
]
#view.py
@ensure_csrf_cookie
def login_authentication(request):
    if request.method != "POST":
        return HttpResponse()
    login_state = {}
    .....

因为完全的静态网页嘛,所以网上常见的{{%csrftoken}}这种方法就不可行了。
对于这种情况,django官方给出了解决方案:
React + Axios + Django前后端分离CSRF问题解决方案_第1张图片
就是用这个 ensure_csrf_cookie,通过cookies的方式将csrftoken发过来。
切记不要将CSRF_COOKIE_SECURE设置为True,否则前前端读取不到这个token。

前端的配置

默认的token在cookies中名字为csrftoken。
因为前后端分离,所以在post之前需要先get一下来获取包含csrftoken的cookies。

axios.get('/Auth/Register')
          .then(()=>{
                      this.usrInfoSending(new Date().getTime())
                    })
          .catch((err) => {
                      this.networkErr(err);
          });

这样get一下之后便得到了csrftoken,便可以正常的post数据了。
忘了说一下,得到的token需要放到Header里,名字为 X-CSRFToken (这个坑了我好久,最开始查到的名字是错的,怎么也验证不过)

    axios.post('/Auth/Register',
            {
                userName: this.state.userName,
                userPassWD: this.state.userPassWD,
                currentTime: timeStamp
            },
            {
                headers:{
                    'X-CSRFToken':cookies.get('csrftoken')
                }
            })
            .then((response) => {
            ......

cookies的获取我直接用了universal-cookie这个库,感兴趣的可以去看看。

基本就这些~

你可能感兴趣的:(前端开发)