如何在没有Jinja的情况下从Flask-wtf获取CSRF令牌?

时间:2019-06-03 13:08:13

标签: python flask flask-wtforms

我可以找到的所有文档和示例都使用“ {{csrf_token()}}”插入令牌。我无法执行此操作,因为我正在使用Vue模板(Jinja不会对此进行解析)

Jinja解析了我的index.html文件,因此我怀疑一个解决方案可能与此有关,但我不知道从哪里开始。

编辑:如果我使用

将其放在index.html中
 <p>{{ csrf_token() }} </p>

它看起来像预期的一样,但是我不确定如何将其放入表单/ axios请求中

1 个答案:

答案 0 :(得分:1)

您将拥有一个基本的Jinja模板,该模板可使用Vue加载页面。

在我的特定情况下,这就是我的操作方式:

对于动态内容:

index.html

{% block content %}
  <div id="vue-container" backend-data="{{ csrf_token() }}"></div>
  <script nonce="{{ csp_nonce() }}">
      $('#vue-container').data('backend_current_user', {{ current_user_data | tojson }});
  </script>
{% endblock %}

{% block scripts %}
  <script src="{{ asset_url_for('index.js') }}"></script>
{% endblock %}

(请注意,这里使用了两种方法;一个元素属性和一个JQuery。实际上,我使用JQuery方法的频率更高,因为它可以更灵活地处理JSON数据)

index.js

import Vue from 'vue'
import Index from '@/components/Index.vue'

new Vue({
  render: function (h) {
    return h(Index, {
      props: {
        backendData: this.$el.attributes.backendData.value,
        backendCurrentUser: $('#vue-container').data('backend_current_user'),
      }
    })
  }
}).$mount('#vue-container')

index.Vue

<script>
export default {
  name: 'Index',
  props: {
    'backendCurrentUser': Object,
    'backendData': String
  },
...

对于静态内容:

实际上,对于csrf令牌,我只是将其放置在页面上足够高的脚本中以便首先加载:

base.html或index.html标头

<script type=text/javascript nonce="{{ csp_nonce() }}">
   $CSRF_TOKEN = '{{ csrf_token() }}';
</script>

,然后在模板/ mixins中使用它:

  methods: {
    ajax_: function (url, action, formData, cb) {
      // eslint-disable-next-line
      formData.csrf_token = $CSRF_TOKEN || null