nuxt-modules / apollo

Nuxt.js module to use Vue-Apollo. The Apollo integration for GraphQL.
https://apollo.nuxtjs.org
MIT License
948 stars 199 forks source link

New way to do auth? #103

Closed kieusonlam closed 6 years ago

kieusonlam commented 6 years ago

Hey guys,

There are some update about auth example at vue-apollo repo https://github.com/Akryum/vue-apollo/blob/master/tests/demo/src/vue-apollo.js

I wonder if we can do the same?

P/S: v3.0.0-beta.14 is released by the way :)

kieusonlam commented 6 years ago

By this way we may have a solution for auth-module as well https://github.com/nuxt-community/auth-module/pull/140

dohomi commented 6 years ago

@kieusonlam just released new version to npm for newest beta on vue-apollo

kieusonlam commented 6 years ago

@dohomi What about createProvider like vue-apollo demo (it have login and logout inside), can we do something like that :)

dohomi commented 6 years ago

@kieusonlam what exactly do you mean? This plugin exposes apolloProvider so you can use it in Vuex-actions or any component related code (https://github.com/nuxt-community/apollo-module#asyncdatafetch-method-of-page-component)

kieusonlam commented 6 years ago

@dohomi Sorry if I'm misunderstanding his demo. I'm not really good as English so I gonna try explain to you as clear as I can :) You can take a look at demo folder https://github.com/Akryum/vue-apollo/tree/master/tests/demo/src

In main.js https://github.com/Akryum/vue-apollo/blob/master/tests/demo/src/main.js you can see:

...
import { createProvider } from './vue-apollo'

...

new Vue({
  ...
  provide: createProvider({}, { router }).provide(),
  ...
}).$mount('#app')

he use createProvider by another file that he has created in vue-apollo.js

Now go into vue-apollo.js in same folder https://github.com/Akryum/vue-apollo/blob/master/tests/demo/src/vue-apollo.js

You can see he create some functions createProvider, onLogin, onLogout and he use that funtion on demo folder. You can take a bit time to look as all that functions.

I just wonder if we can do something like vue-apollo.js inside this plugin which have login and logout by the default.

For example in the apollo config file instead of

import { ApolloLink, concat, split } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { WebSocketLink } from 'apollo-link-ws'
import { getMainDefinition } from 'apollo-utilities'
import 'subscriptions-transport-ws' // this is the default of apollo-link-ws

export default (ctx) => {
  const httpLink = new HttpLink({uri: 'https://api.graph.cool/simple/v1/' + process.env.GRAPHQL_ALIAS})
  const authMiddleware = new ApolloLink((operation, forward) => {
    //This function is called before every request. Update ctx.req.session and window.__NUXT__.state.session
    //To point to wherever you store your token
    const token = process.server ? ctx.req.session : window.__NUXT__.state.session
    operation.setContext({
      headers: {
        Authorization: token ? `Bearer ${token}` : null
      }
    })
    return forward(operation)
  })
  // Set up subscription
  const wsLink = new WebSocketLink({
    uri: `wss://subscriptions.graph.cool/v1/${process.env.GRAPHQL_ALIAS}`,
    options: {
      reconnect: true,
      connectionParams: () => {
        const token = process.server ? ctx.req.session : window.__NUXT__.state.session
        return {
          Authorization: token ? `Bearer ${token}` : null
        }
      }
    }
  })

  const link = split(
    ({query}) => {
      const {kind, operation} = getMainDefinition(query)
      return kind === 'OperationDefinition' && operation === 'subscription'
    },
    wsLink,
    httpLink
  )

  return {
    link: concat(authMiddleware, link),
    cache: new InMemoryCache()
  }
}

We just need to do something like this:

{
  httpEndpoint: process.env.VUE_APP_GRAPHQL_HTTP || 'http://localhost:4000/graphql',
  wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || 'ws://localhost:4000/graphql',
  tokenName: AUTH_TOKEN,
  persisting: false,
  websocketsOnly: false,
  // ssr: false,
  // link: myLink,
  // cache: myCache,
  // apollo: { ... }
}

You might want to see https://github.com/Akryum/vue-cli-plugin-apollo which he use to create createProvider.

Then everyone don't need to write too much code and because we default have some thing like Login / Login funtions, so we can do something like this.$apollo.login(AUTH_TOKEN) it will easier for everyone. And by this way maybe we can apollo login schema in auth-module as well.

That what I thought.

dohomi commented 6 years ago

@kieusonlam thanks for your suggestion. its actually a nice idea if you have time to submit a PR I'm happy to assist.

kieusonlam commented 6 years ago

I'm working on it. I don't know if I do it right. Here is my fork: https://github.com/kieusonlam/apollo-module/blob/master/plugin.js Currently, I don't know how to put setToken function in $apollo, and the right way to get the module options.

Should I submit a WIP PR.

dohomi commented 6 years ago

@kieusonlam how about to provide a plugin to publish some internal functions:

$apolloHelpers:{
  setToken:() => {
    // sets the token
  }
}

sure you can provide a PR out of your fork and then we can ask other users to join for a best practice setup

dohomi commented 6 years ago

@kieusonlam as v4 just published as pre-alpha I think we took care of all of your ideas. I will close this now as login/logout handling is fully covered with this plugin