【问题标题】:Nuxt auth update auth on custom requestsNuxt auth 根据自定义请求更新身份验证
【发布时间】:2019-08-21 02:38:04
【问题描述】:

从 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 获取的令牌和用户数据吗?如果需要,然后从那里使用它?

【问题讨论】:

    标签: javascript node.js vuejs2 nuxt.js


    【解决方案1】:

    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 auth 时遇到了数百万个问题,只有这样才能帮助我解决问题……

    【讨论】:

    • 我发现 Nuxt 模块是噩梦,文档已经过时
    猜你喜欢
    • 2021-09-06
    • 2019-04-24
    • 1970-01-01
    • 2021-05-24
    • 2016-07-22
    • 1970-01-01
    • 2020-04-01
    • 2022-12-10
    • 1970-01-01
    相关资源
    最近更新 更多