Closed thattejada closed 6 years ago
The fetchUser
hook can be used for this I think, it is called only if a user has successfully logged in.
Thanks @samtgarson, but, how can I call that method in my nuxt app immediately the OAuth flow is completed?, can you give me any example? I can't figure out how to do that
I'm not actually sure what your requirement is. You can put any logic you want to be triggered as soon as the user has logged in in any component or store (e.g. in a created
method or using nuxtServerInit
) and it will be called when the app boots.
You know whether or not the user has logged in based on if the OAuth vuex module has been populated.
What I'm trying to do is:
But I can't get the fetchUser method triggered
This is my nuxt.config.js:
oauth: {
sessionName: 'appSession',
secretKey: process.env.SECRET_KEY,
oauthHost: process.env.OAUTH_HOST,
oauthClientID: process.env.OAUTH_CLIENT_ID,
oauthClientSecret: process.env.OAUTH_CLIENT_SECRET,
scopes: process.env.OAUTH_CLIENT_SCOPE.split(','),
accessTokenPath: '/access_token',
getOauthHost: req => req.params.oauth_host,
onLogout: (req, res) => {
// do something after logging out
},
fetchUser: (accessToken, request) => {
/**
* access to the store and send the token to
* the backend
*/
}
},
I'm sorry a lot but I'm newbie to Nuxt and Vue world
In the top level of your store store/index.js
, create an action like this:
nuxtServerInit ({ state, dispatch }) {
const { accessToken } = state.oauth
if (accessToken) {
// the user is logged in, dispatch your action
// to send token to backend
dispatch('fetchAccessToken', accessToken)
} else {
// the user is not logged in
}
}
Nuxt will call this action on the server side as part of the initial load of the app.
Thanks @samtgarson, but, I tried to implement the nuxtServerInit in store/index.js
this way:
export const actions = {
nuxtServerInit ({ state, dispatch }) {
console.log("The state", state) // <-- I'm logging the state to see if oauth module is loaded, but it's not
const { accessToken } = state.oauth
if (accessToken) {
console.log("logged in")
// the user is logged in, dispatch your action
// to send token to backend
dispatch('fetchAccessToken', accessToken)
} else {
// the user is not logged in
console.log("not logged in")
}
}
}
The problem is that the state is not loading / showing the oauth module: The console.log("The state", state) shows:
The state { auth:
{ accessToken: null,
expiresIn: null,
tokenType: null,
refreshToken: null },
groups: { groupList: [] },
messages:
{ messageList: [],
messageTypeToRequest: '',
selectedMessage: {},
newMessage: '' },
users: { usersList: [], userGroup: 'all' } }
Those are the store modules I have:
But the oauth module is not being loaded in that moment when the nuxtServerInit method runs
My whole nuxt.config.js is:
require('dotenv').config()
module.exports = {
modules: [
'nuxt-oauth',
'@nuxtjs/axios',
],
/*
** Headers of the page
*/
head: {
title: 'Buz',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'my description' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' }
]
},
/*
** Customize the progress bar color
*/
loading: { color: '#3B8070' },
plugins: [
'~plugins/vuetify.js',
'~/plugins/axios.js',
// '~/plugins/vue-tags-input.js',
],
css: [
'~assets/app.styl',
// '@voerro/vue-tagsinput/dist/style.css'
],
/*
** Build configuration
*/
build: {
publicPath: 'http://localhost/buz/',
vendor: [
'axios',
'vuetify'
],
/*
** Run ESLint on save
*/
extend (config, { isDev, isClient }) {
/*if (isDev && isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}*/
}
},
axios: {
// See https://github.com/nuxt-community/axios-module#options
baseURL: process.env.BASE_URL,
},
oauth: {
sessionName: 'appSession',
secretKey: process.env.SECRET_KEY,
oauthHost: process.env.OAUTH_HOST,
oauthClientID: process.env.OAUTH_CLIENT_ID,
oauthClientSecret: process.env.OAUTH_CLIENT_SECRET,
scopes: process.env.OAUTH_CLIENT_SCOPE.split(','),
// authorizationPath: '/authorize',
accessTokenPath: '/access_token',
getOauthHost: req => req.params.oauth_host,
onLogout: (req, res) => {
// do something after logging out
},
fetchUser: (accessToken, request) => {
// do something to return the user
const user = User.findByToken(accessToken, request)
return user
}
},
}
@diegotejadav have you upgraded to 2.0.0?
Also: unless you have a User.findByToken
method defined somewhere, this will not work: const user = User.findByToken(accessToken, request)
You need to define your own fetchUser
method if you want nuxt-oauth to populate the store with your user object
Thank you so much @samtgarson, I was outdated with the 1.1.0 version, after that all the pieces you suggested these days fit for a final solution.
Now when my user authenticates with the authorization server, immediately it is authenticated with the resource server, and I can access to the endpoints I need.
I realized that I need more of the async world and promises with JS.
If someone need an approach like this, the solution was:
store/index.js:
export const actions = {
async nuxtServerInit ({ state, dispatch }) {
const { accessToken } = state.oauth
if (accessToken) {
console.log("logged in")
const success = await dispatch('auth/convertToken', accessToken)
} else {
console.log("not logged in")
}
}
}
store/auth.js:
export const state = () => ({
accessToken: null,
expiresIn: null,
tokenType: null,
refreshToken: null
})
export const mutations = {
setConvertData (state, data) {
state.accessToken = data['access_token']
state.expiresIn = data['expires_in']
state.tokenType = data['token_type']
state.refreshToken = data['refresh_token']
}
}
export const actions = {
convertToken ({ commit, state }, accessToken) {
const params = {
grant_type: 'convert_token',
client_id: '<client_id>',
client_secret: '<client_secret>',
backend: '<backend-name>-oauth2',
token: accessToken
}
return this.$axios.post('/auth/convert-token', params)
.then((res) => {
commit('setConvertData', res.data)
})
}
}
How can I call a custom function right after the user logs in?