Salut,
J'apprends depuis quelques temps à utiliser VueJS 2. Je trouve ce framework vraiment simpa et simple a apprendre mais je rencontre un problème.
Pour le moment mon appli comporte quelques pages qui sont gérée par Vue-routeur sans problème.
Mais je souhaite créer un système d'utilisateur avec une page de connection si l'utilisateur ne s'est pas identifiée.
Mais voilà, je ne sais pas trop comment m'y prendre, j'ai essayer un store tout simple :
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
const state = {
username: null,
email,
token: null
}
const mutations = {
SET_USER (state, user) {
state.user = user
},
SET_TOKEN (state, token) {
state.token = token
},
GET_TOKEN (state) {
return state.token
},
LOGIN (state, username, password) {
axios.get('http://monsite.com/index.php?section=login&page=login&username=' + username + '&password=aze').then((response) => {
if (Object.keys(response.data.results).length === 0) {
state.username = ''
state.token = ''
console.log('Connect False')
return false
} else {
state.username = response.data.results.login.username
state.token = response.data.results.login.token
console.log('Connect : ' + state.token)
return response.data.results.login.token
}
})
}
}
export default new Vuex.Store({
state,
mutations
})
lorsque je suis dans la vue 'login.vue' j'ai ceci :
<script>
import axios from 'axios'
export default {
data () {
return {
username: '',
password: ''
}
},
methods: {
submit: function () {
var store = this.$store
store.commit('LOGIN', 'monUser', 'monPassword')
console.log(store.commit('GET_TOKEN')) // Problème, ceci retour null ???
}
}
</script>
Mon problème c'est que le GET_TOKEN me retourne null alors qu'il devrait retourner le token rendu par LOGIN
Faut-il faire autrement afin de faire un système d'authentification sous VueJS ? avez-vous une idée ?
Cordialement,
Jielde.
Parce que la réponse que tu attends du getToken, dépend de la réponse du serveur ping. axios a bien été executé son code avant.
Sauf que ton script ne va pas attendre qu'axios recoive sa réponse puis executer les autres opérations.
Le mieux que tu puisses faire c'est ceci:
methods: {
// async !important (si tu utilises babel, ça devrait transpiler correctement)
async submit (e) {
const { commit } = this.$store
// await !important (si tu utilises babel, ça devrait transpiler correctement)
await axios.get('https://.../')
.then((response) => {
if (false /* a remplacer par ta condition fail OU voir le com. de .catch() */) { // -1
commit('LOGIN_FAILURE') // Mutation en cas d'echec (définir les états)
return
}
commit('LOGIN_SUCCESS', response.data.results) // Mutation en cas de succès (définir les états)
// La suite de ton opération ici...
console.log('Mon token est', this.getToken) // @return 'Mon token est 42ca4cf4f3b358799d2c89ac43dc7ad5.8b07a0bb87e164c'
})
.catch(() => commit('LOGIN_FAILURE')) // +1 => ton serveur doit retourner un code d'erreur HTTP 401/403
// OU ici. (Uniquement possible grace aux async/await.)
console.log(this.getToken) // @return '42ca4cf4f3b358799d2c89ac43dc7ad5.8b07a0bb87e164c'
}
}
Lire le(s) code/commentaire(s) aussi.
Parce qu'un commit ne sert pas à retourner ton état.
Tu dois utiliser l'helper mapGetters
dans ce cas ci (OU mapState
). Voir l'exemple ci-dessous:
// Définition des getters
const getters = {
getToken (state) {
return state.token
},
autreGetter (state) {
return state.proutprout
}
}
export default new Vuex.Store({
getters,
state,
mutations
})
Puis dans l'une de tes vues,
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
...mapGetters(['getToken']) // Ne récupère que le getter getToken, et celui-ci est accessible via this.getToken.
}
}
Merci PhiSyX pour ta réponse,
J'ai fait ce que tu m'a demandée mais j'ai toujours le même résultat, je m'explique.
En premier je fait un :
store.commit('LOGIN', 'monUser', 'monPassword')
donc le code est :
axios.get('http://monsite/index.php?section=login&page=login&username=test&password=password).then((response) => {
console.log(response.data)
if (Object.keys(response.data.results).length === 0) {
console.log('1>Connect False') // Mauvais utilisateur ou password
return false
} else {
state.username = response.data.results.login.username
state.token = response.data.results.login.id_token
console.log('1> Connect : ' + state.token) // Ok, l'utilisateur et password correspond à quelque chose
return response.data.results.login.id_token
}
})
Ensuite, j'affiche mon token dans la console
console.log('2> Token :' + this.getToken)
ma console retourne :
2> Token :null
1> Connect : 42ca4cf4f3b358799d2c89ac43dc7ad5.8b07a0bb87e164c
Normalement la ligne 1> Connect devrait être avant la ligne 2>Token et cette dernière devrais retourner Token : suivi de 42ca4cf4f3b358799d2c89ac43dc7ad5.8b07a0bb87e164c.
Hum.... une idée ?
Merci énormément PhiSyX pour ta réponse,
Ceci fonctionne parfaitement je vais pouvoir avancer dans ma formation.
Le problème en faite c'était que axios ne bloquait pas le déroulement du script et pouvait répondre un peut plus tard.
await permet donc d'attendre que le script soit fini avant de passer à la ligne suivante.
Merci