Приложение django / nuxt остается в системе после обновления - PullRequest
1 голос
/ 14 февраля 2020

Я пытаюсь выяснить, почему мое приложение nuxt не выходит из системы должным образом. Когда я выхожу из системы, нажимая кнопку «Выйти», и я переоцениваю sh страницу, на которой я все еще авторизован.

Мое приложение - это докернизированный django / DRF + nuxt с отдельной настройкой внешнего интерфейса + бэкэнда.

Я искал в журналах и вижу в django Unauthorized: /api/auth/token/destroy/

Я не уверен, почему я вижу эту ошибку. Это проблема с django настройками или кодом внешнего интерфейса?

макеты / по умолчанию. vue

  <template>
    <div class="mt-2">
      <b-navbar toggleable="md" type="dark" variant="info">
        <b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
        <b-collapse is-nav id="nav-collapse">

          <b-navbar-nav>
            <b-nav-item to="/">Events</b-nav-item>
            <b-nav-item to="/monitor">Monitor</b-nav-item>
            <b-nav-item to="/configuration">Configuration</b-nav-item>
            <b-nav-item to="/reports">Reports</b-nav-item>

          </b-navbar-nav>

          <b-navbar-nav class="ml-auto" v-if="$store.state.loggedIn">
            <b-nav-text>{{ $store.state.user.username }}</b-nav-text>

            <b-nav-item @click="logout()">Logout</b-nav-item>
          </b-navbar-nav>

          <b-navbar-nav class="ml-auto" v-if="!$store.state.loggedIn">
            <b-nav-item to="/login">Login</b-nav-item>
          </b-navbar-nav>
        </b-collapse>
      </b-navbar>
      <div class="mt-2">
        <nuxt/>

      </div>
    </div>
  </template>

  <script>

  export default {



  methods: {
      logout () {
        this.$store.dispatch('logout')
        this.$router.push('/')
      }
    }
  }
  </script>

сервер / аутентификация. js

  const axios = require('axios')
  const app = require('express')()

  const API_URI = process.env.API_URI

  app.post('/login/', async (req, res) => {
    try {
      const result = await axios.post(API_URI + '/auth/token/create/', req.body)
      req.session.authToken = result.data.auth_token
      await req.session.save()
      return res.json({"OK": true})
    } catch (e) {
      console.log(e)
      return res.status(401).json({ error: 'Bad credentials' })
    }
  })

  app.post('/logout/', async (req, res) => {
    delete req.session.authToken
    await req.session.save()
    axios.post(API_URI + '/auth/token/destroy/')
    return res.status(200).json({ ok: true })
  })

  module.exports = {
    path: '/auth',
    handler: app
  }

выход из системы. vue

export default {
state: () => ({
loggedIn: false,
user: null
}),
actions: {
   async nuxtServerInit ({ commit }, { req, app }) {
    console.log('nuxtServerInit', req.session.authToken)
   if (req.session.authToken) {
      const data = await app.$axios.$get('/api/auth/me/')
      commit('SET_USER', data)
    } else {
      commit('SET_USER', null)
   }
 },
  async login ({ commit }, creds) {
    await this.$axios.$post('/auth/login/', creds)
    const data = await this.$axios.$get('/api/auth/me/')
    commit('SET_USER', data)
  },
  logout ({ commit }) {
    this.$axios.$post('/auth/logout/')
    commit('SET_USER', null)
  }
},
mutations: {
  SET_USER (state, user) {
    if (user) {
      state.loggedIn = true
      state.user = user
     } else {
      state.loggedIn = false
      state.user = null
    }
  }
}

}

API. js

const proxy = require('http-proxy-middleware')
const app = require('express')()

// API_URI should end in /api/, and we remove that part in the URL.
app.use(proxy({
target: process.env.API_URI,
prependPath: false,
changeOrigin: true,
auth: false,
logLevel: 'debug',
onProxyReq(proxyReq, req, res) {
    if (req.session.authToken) {
    proxyReq.setHeader('Authorization', 'Token ' + req.session.authToken)
    }
    // workaround for bodyParser incompat
    // https://stackoverflow.com/questions/25207333/socket-hang-up-error-with-nodejs/25651651#25651651
    if (req.body) {
    let bodyData = JSON.stringify(req.body)
    // in case if content-type is application/x-www-form-urlencoded -> we need to change to application/json
    proxyReq.setHeader('Content-Type','application/json')
    proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData))
    // stream the content
    proxyReq.write(bodyData)
    }
},
async onProxyRes(proxyRes, req, res) {
    // if the API returns a 401, the token can be considered invalid. Delete the token.
    if (proxyRes.statusCode === 401) {
    delete req.session.authToken
    await req.session.save()
    }
}
}))

module.exports = {
path: '/api',
handler: app
}    

settings.py

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rest_framework",
    "rest_framework.authtoken",
    "corsheaders",
    "djoser",
    'django_celery_beat',
    'django_celery_results',
    "accounts",
]

    MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

    REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework.authentication.BasicAuthentication",
        "rest_framework.authentication.SessionAuthentication",
        "rest_framework.authentication.TokenAuthentication",
    ),
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 100,
}
...