feathersjs-ecosystem/feathers-authentication-management

Setting up authManagement in Nuxt.js gives not authenticated error (feathers-vuex)

ImreC opened this issue · 6 comments

ImreC commented

I am trying to implement the authManagement module in a Vue frontend (Nuxt.js) but I can't get it to work.

Steps to reproduce

  • Added the authManagement service to the feathers client.
  • Created a route that takes the verifyToken from an URL parameter

User flow:

  • User signs up with email and password
  • feathers client creates a cookie containing an accessToken
  • User gets email containing link with verifyToken in parameter
  • User clicks the link and ends up in verify.vue
  • Verify.vue dispatches an auth/authenticate action
  • Verify.vue dispatches an 'authManagement/create' action containing the {action: action, value:token} object. (In my mind the same as sending a post request to the /authManagement endpoint

Expected behavior

The user is authenticated and posting the token verifies the user

Actual behavior

Server side error message (I think on dispatching auth/authenticate):

type: 'FeathersError',
  name: 'NotAuthenticated',
  message: 'Could not find stored JWT and no authentication strategy was given',
  code: 401,
  className: 'not-authenticated'

Client side error message (set as createError on the authManagement state):

errorOnCreate:Object
hook:Object
app:Object
data:Object
id:undefined
method:"patch"
params:Object (empty)
path:"users"
service:Object
type:"before"
message:"An id must be provided to the 'patch' method"
name:"Error" 

What I don't understand

Shouldn't the userid of the verification action be taken from the token?
Why is my cookie not recognized?
Is there anything I am missing?
I will happily contribute to the Vue docs if I get this working

Code

feathers.js in plugins (client)

import feathers from '@feathersjs/client'
import io from 'socket.io-client'
import { CookieStorage } from 'cookie-storage'
import authManagementService from 'feathers-authentication-management'

const socket = io(process.env.baseUrl)


const feathersClient = feathers()
  .configure(feathers.socketio(socket))
  .configure(feathers.authentication({ storage: new CookieStorage() }))
  .configure(authManagementService())

export default feathersClient

Vuex store index.js

import Vue from 'vue' // eslint-disable-line import/no-extraneous-dependencies
import Vuex from 'vuex' // eslint-disable-line import/no-extraneous-dependencies
import feathersVuex from 'feathers-vuex'
import feathersClient from '../plugins/feathers'
import { initAuth } from 'feathers-vuex/lib/utils'

const { service, auth } = feathersVuex(feathersClient, { idField: '_id' })

Vue.use(Vuex)

const store = new Vuex.Store({
  plugins: [
    service('/products'),
    service('/users'),
    auth({ userService: '/users' }),
    service('authManagement')
  ],
  state: {},
  actions: {
    nuxtServerInit ({ commit }, { req }) {
      return initAuth({
        commit,
        req,
        moduleName: 'authManagement',
        cookieName: 'feathers-jwt'
      })
    }
  }
})

export default () => store

script in verify.vue

<script>
export default {
  methods: {
    async verifyToken() {
      const authData = {
        action: 'verifySignupLong',
        value: this.$route.query.token
      }
      console.log(authData)
      await this.$store.dispatch('auth/authenticate')
      await this.$store.dispatch('authManagement/create', authData)
      this.$router.push('/onboarding')

    }
  },
  created () {
    this.verifyToken()
  }
}
</script>

I don't use Vue so I can't help. Perhaps you can ask @marshallswain who wrote feathers-vuex (called Marshall on Feathers Slack).

It seems that even though you are setting up the feathers client with the cookie storage module, the JWT is still not available to the feathers client as a cookie in the server environment. Hence, the error 'Could not find stored JWT and no authentication strategy was given'.

I recommend using a debugger to set a breakpoint in your feathers-client.js so you can see if you can get access to the cookie in that context. I wrote an article on debugging Nuxt that might still be helpful even though I wrote it for a Nuxt beta release. https://codeburst.io/debugging-nuxt-js-with-visual-studio-code-724920140b8f

If you'd like to push your code to GitHub, I'd be glad to pull and troubleshoot.

ImreC commented

Just pushed some code to a repo here
https://github.com/ImreC/feathers-test-auth-mgt

I have a hard time debugging this, since I haven't been coding that long and this is all pretty new to me. Really appreciate you taking a look.

ImreC commented

@marshallswain really rookie mistake. I forgot to set the cookie to enabled on server side. Server side error is fixed. The one on the client ("An id must be provided to the 'patch' method") persists. I will look into that later.

ImreC commented

Ok just tried it again with an axios post request instead. This works flawlessly. So what I still don't understand is why I have to provide an id to the patch method when I can just send a post request to the /authmanagement endpoint without any ids. Obviously this is something I can code around. I just don't get it.

ImreC commented

Ok, I feel this is off topic here. I'll close the issue. Thanks for the help so far :).