Vue项目和flask框架前后端分离session的坑

Vue项目和flask框架前后端分离session的坑

  • Vue的项目启动
  • Flask的项目启动
  • 前后端分离

Vue的项目启动

一般来说,现在的开发环境都是使用自动化工具进行项目创建和开发。
所以,在测试时,自动化工具会帮我们创建一个本地服务,
npm run dev 指令创建的服务
一般创建完成后会给出一个地址

1
2
3
 DONE  Compiled successfully in 1464ms                                                                        5:01:23 PM

 I  Your application is running here: http://localhost:8080

Flask的项目启动

在项目文件夹打开cmd
将项目的python文件设置为FLASK_APP环境变量
之后启动服务

1
2
3
set FLASK_APP=test.py

python -m flask run

Flask中文文档

启动之后

1
2
3
4
5
6
7
D:\Flask>python -m flask run
 * Serving Flask app "test.py"
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

前后端分离

之前已经讲述了前后端各自的服务启动
我们可以看到,他们各自的地址是不尽相同的,端口肯定是不一样的
这意味着,当前端发送请求到后端时,会产生跨域问题

你会在浏览器的控制台看到这样的错误
Access to XMLHttpRequest at ‘http://localhost:5000/e/state’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

这就是跨域请求产生的问题
我们可以在后台py脚本添加返回头解决跨域请求问题

但是,如果你使用session的话,会产生跨域资源共享问题
这时你需要在前端请求设置
withCredentials: true
我使用的是axios,配置如下

1
2
3
4
5
6
7
8
9
10
11
this.$axios({
        method: 'post',
        url: 'http://localhost:5000/e/login',
        data:{
          'fun' : 'login',
          "number": this.number,
          "password": this.password,
          'radio': this.radio
        },
        withCredentials: true  //解决跨域session丢失  需前后端一同配置
      })

然后后端脚本配置如下

1
2
3
4
5
6
7
8
9
10
11
12
@app.after_request
def af_req(resp):  #解决跨域session丢失
    resp = make_response(resp)
    resp.headers['Access-Control-Allow-Origin'] = 'http://localhost:8080'
    resp.headers['Access-Control-Allow-Methods'] = 'PUT,POST,GET,DELETE,OPTIONS'
    #resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
    resp.headers['Access-Control-Allow-Headers'] = 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild'
    resp.headers['Access-Control-Allow-Credentials'] = 'true'

    resp.headers['X-Powered-By'] = '3.2.1'
    resp.headers['Content-Type'] = 'application/json;charset=utf-8'
    return resp

这里要注意的是Access-Control-Allow-Origin,源要是你的前端ip地址,不能使用通配

Access-Control-Allow-Credentials是允许前端携带cookie

一般完成这样的配置后不会出现跨域请求、session丢失等的问题了

然而我还是有问题,而这个问题出在前端请求上

我设置了两个不同的请求,一个是关于登录的,一个是验证登录的

登录后后端存储session,验证则判断session是否存在

理论上很美好,然而实际使用中我发现我可以成功登录

但是,判断session上却出现了问题

经过测试发现,在登录上的session存储没有问题,每次发送登录请求后台打印session字典都ok

验证session的请求打印的session却是空字典

我懵了!之后我疯狂检查代码发现我两个请求的url不同

一个是 localhost 另一个是 127.0.0.1

这就是问题所在,这两者是不同源的,sessionid不同,无法获取对方的session

localhost简介、localhost与 127.0.0.1 及 本机IP 的区别

127.0.0.1与localhost不同源