Nuxt auth根据自定义请求更新auth

时间:2019-08-17 21:28:59

标签: javascript node.js vuejs2 nuxt

在nuxt auth网站上,我看到了以下内容:

setUserToken(token)
Returns: Promise
Set the auth token and fetch the user using the new token and current strategy.

TIP: This function can properly set the user after registration

this.$auth.setUserToken(token)
  .then(() => this.$toast.success('User set!'))

试图使用它,它表示方法未定义,在源文件中查找,并且没有一种方法像这样。

我对此不太满意,但是注册后如何使用nuxt / auth模块或除login / loginWith之外的任何内容设置用户和令牌?

如果没有选择,为什么在文档中有?

我还需要知道是否需要创建自定义身份验证,我需要同时使用cookieslocalstorage还是其中之一? 它说cookie用于服务器端,存储用于客户端。 我可以仅使用cookie,并且可以在nuxtServerInit上获取cookie的令牌,并设置vuex存储区中api提取的令牌和用户数据吗?然后在需要时从那里使用它吗?

1 个答案:

答案 0 :(得分:0)

Nuxt / auth模块很长时间伤害了我的大脑,今天我创建了自定义模块:

首先,我有这个商店结构:

store/
-- index.js
-- mutations.js
-- actions.js
-- state.js
-- getters.js
middleware/
-- redirectIfAuth.js
-- redirectIfNotAuth.js
layouts/
default.vue -> has redirectIfNotAuth.js
guest.vue -> has redirectIfAuth.js
pages/
-- login/
---- index.vue -> uses guest.vue as layout
-- dashboard/
----- index.vue -> uses default.vue as layout without declaration

Index.js里面,我有

import state from './state'
import * as actions from './actions'
import * as mutations from './mutations'
import * as getters from './getters'

export default {
  state,
  getters,
  mutations,
  actions,
  modules: {}
}

State.js里面,我有

export default () => ({
  user: null,
  token: null,
  headers: null
})

Actions.js里面,我有

const cookieparser = process.server ? require('cookieparser') : undefined
// importing server based cookie library

export async function nuxtServerInit ({ commit }, { req, res }) {

  // If we have any axios requests we need to add async/await
  // And since this works on server mode, we don't need to check is it server

  let token = null
  if (req.headers.cookie) {
    const parsed = cookieparser.parse(req.headers.cookie)
    try {
      token = parsed.authToken
    } catch (e) {
      console.log(e)
    }
  }
  // If we have token within cookies we get user data from api and we pass Autorization headers with token
  if (token !== null && token !== false) {
    await axios.get('/api/auth/me', {
      headers: {
        'Authorization': token
      }
    }).then((response) => {
      // If  we get user data we set it to store
      commit('setUser', response.data.data)
      commit('setToken', token)
      commit('setHeaders', token)
    }).catch((error) => {
      // If we get error, we should logout user by removing data within cookies and store
      // Additionally you can create specific code error on backend to check if token is expired or invalid
      // and then check for status code and then remove data
      commit('setUser', null)
      commit('setToken', null)
      res.setHeader('Set-Cookie', [`authToken=false; expires=Thu, 01 Jan 1970 00:00:00 GMT`])
      // This is only way I found useful for removing cookies from node server
      console.warn(error)
    })
  }
}

Mutations.js里面,我有

export const setToken = (state, payload) => state.token = payload

export const setUser = (state, payload) => state.user = payload

export const setHeaders = (state, payload) => {
  state.headers = {
    headers: {
      'Authorization': payload
    }
  }
}

Getters.js里面,我有

export const getUser = (state) => state.user
export const getToken = (state) => state.token
export const getHeaders = (state) => state.headers

第二,我创建了两个中间件,并且看起来nuxt中间件在服务器和客户端上都可以工作,所以我需要在服务器和客户端上都需要库,然后检查了哪一侧,然后尝试获取令牌以进行进一步研究如果您包括但不检查服务器和客户端,而是使用其中之一,则您的模板将不会呈现,但会在客户端上显示req的未定义错误,而在服务器上则不会显示任何内容。

redirectIfAuth.js里面,我有

const cookieparser = process.server ? require('cookieparser') : undefined
const Cookie = process.client ? require('js-cookie') : undefined
export default function ({ app, redirect, req }) {
  let token = null
  if (process.server) {
    if (req.headers.cookie) {
      const parsed = cookieparser.parse(req.headers.cookie)
      try {
        token = parsed.authToken
      } catch (e) {
        console.log(e)
      }
    }
  } else if (process.client) {
    token = Cookie.get('authToken')
  }
  if (token && token !== false) {
    app.store.commit('setToken', token)
    app.store.commit('setHeaders', token)
    if (app.store.state.user) {
      if (app.store.state.user.roles.includes('customer')) {
        return redirect({
          name: 'customer-slug',
          params: { slug: app.store.state.user.username }
        })
      } else if (app.store.state.user.roles.includes('admin')) {
        return redirect({
          name: 'dashboard'
        })
      } else {
        return redirect({
          name: 'index'
        })
      }
    } else {
      return redirect({
        name: 'index'
      })
    }
  }
}

redirectIfNotAuth.js里面,我有

const cookieparser = process.server ? require('cookieparser') : undefined
const Cookie = process.client ? require('js-cookie') : undefined
export default function ({ app, redirect, route, req }) {
  let token = null
  if (process.server) {
    if (req.headers.cookie) {
      const parsed = cookieparser.parse(req.headers.cookie)
      try {
        token = parsed.authToken
      } catch (e) {
        console.log(e)
      }
    }
  } else if (process.client) {
    token = Cookie.get('authToken')
  }
  if (token === null || token === false) {
    return redirect({
      name: 'login',
      query: {
        redirect: route.fullPath
      }
    })
  }
}

现在,我们在页面或布局中使用以下中间件:

export default {
  middleware: ['redirectIfAuth']
}

export default {
  middleware: ['redirectIfNotAuth']
}

登录:

async login () {
      if (this.form.email !== '' && this.form.password !== '') {
        await this.$axios.post('/api/auth/login', this.form).then((response) => {
          this.$store.commit('setUser', response.data.data)
          this.$store.commit('setToken', 'Bearer ' + response.data.meta.access_token)
          this.$store.commit('setHeaders', 'Bearer ' + response.data.meta.access_token)
          Cookie.set('authToken', 'Bearer ' + response.data.meta.access_token, { expires: 365 })
          // Cookie.set('authUser', response.data.data, { expires: 365 }) if you need user data within cookies
          if (this.$route.query.redirect) {
            this.$router.push(this.$route.query.redirect)
          }
          this.$router.push('/')
        })
      }
    }

注销:

async logout () {
   await this.$axios.post('/api/auth/logout', {}, this.headers)
   // Cookie.remove('authUser') if exists
   Cookie.remove('authToken')
   this.$router.push('/')
}

我希望这可以帮助某人或某人从中获得一些想法,从而做出其他事情。我在使用nuxt官方认证时遇到了数百万个问题,只有这样才能帮助我解决问题...