Bonjour à tous.
Au sein de mon extension chrome je dois récupérer le token renvoyée par mon process d'authentification Oauth.
Si l'authentification se fait bien, je ne parviens pas à récupérer la valeur de retour.
Pour implémenter cela j'ai une méthode déclarée dans mon composant enfant Login.vue (chargé depuis le parent App.vue) et dans lequel un bouton appelle ma fonction via async login()
async login() {
const CLIENT_SECRET = "***********************************";
const redirectURL = browser.identity.getRedirectURL();
const clientID = "*******";
const scopes = "openid";
let loginURL = `${urlAuth}/auth`;
loginURL += `?client_id=${clientID}`;
loginURL += "&response_type=code";
loginURL += "&state = default";
loginURL += `&redirect_uri=${encodeURIComponent(redirectURL)}`;
loginURL += `&scope=${encodeURIComponent(scopes)}`;
let url = {};
url = await browser.identity.launchWebAuthFlow({
interactive: true,
url: loginURL,
});
let hash;
const JsonUrl = {};
const hashes = url.slice(url.indexOf("?") + 1).split("&");
for (let i = 0; i < hashes.length; i + 1) {
hash = hashes[i].split("=");
JsonUrl[hash[0]] = hash[1];
}
const code = JsonUrl.code;
const details = {
redirect_uri: redirectURL,
client_id: "*******",
grant_type: "authorization_code",
code,
client_secret: CLIENT_SECRET,
scope: "openid",
};
let detailsBody = [];
Object.keys(details).forEach(((property) => {
const encodedKey = encodeURIComponent(property);
const encodedValue = encodeURIComponent(details[property]);
detailsBody.push(`${encodedKey}=${encodedValue}`);
}));
detailsBody = detailsBody.join("&");
// let user = {};
fetch(`${urlAuth}/token`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: detailsBody,
}).then((response) => (response.json()))
.then((data) => { this.user = data.access_token; });
this.$emit("access-token", this.user);
},
Ce que je veux
Récupérer le résultat de ma requête fetch
Ce que j'obtiens
Etant donné que je suis dans une extension, je ne peux rien envoyer dnas la console. Donc j'essaie d'envoyer le résultat dans une props du composant que je récupére et affiche dans le parent App.vue via ce code
<Login
v-if="!isConnected"
@access-token="updateToken($event)"
/>
...
props: {
token: {
type: String,
default: "Par défaut",
required,
},
methods: {
updateStatus(statut) {
this.token = token;
},
Mais ma props token garde sa valeur par défaut. Rien n'est transmis et je ne sais même pas si le résultat du fetch est récupéré.
Un peu d'aide serait apprcié.
Merci :)
Pour info la requête fonctionne. Je suis bien dirigé vers la page de login pour m'authentifier, la connexion est effective (l'interface admin affiche bien la session ouverte)
Est-ce que tu fais quelque chose après avoir appelé la fonction login()? Je me demande s'il ne faudrait pas que tu fasses un await fetch(...)
.
J'ai allégé ma fonction login pour mieux analyser. J'ai donc enlever pour l'instant la requête fetch.
login() {
// const CLIENT_SECRET = "*********************";
const redirectURL = browser.identity.getRedirectURL();
const clientID = "poplab-front";
const scopes = "openid";
let loginURL = `${urlAuth}/auth`;
loginURL += `?client_id=${clientID}`;
loginURL += "&response_type=code";
loginURL += "&state = default";
loginURL += `&redirect_uri=${encodeURIComponent(redirectURL)}`;
loginURL += `&scope=${encodeURIComponent(scopes)}`;
let url = {};
url = browser.identity.launchWebAuthFlow({
interactive: true,
url: loginURL,
}).then((response) => (response.json()))
.then((response) => { this.data = response; return response; });
url.then((result) => result.json())
.then((result) => { console.log(result); });
},
Et ça ne donne rien de mieux.
Je ne parviens pas à récupérer le rsultat de mon appel au login oAuth2
Je tente une autre approche.
Dans mon App.vue je charge les components conditionnellement, dont mon composant Login qui contient le bouton au sein de l'élément "form" :
<Login
v-if="!isConnected"
@is-connected="updateStatus($event)"
@user-firstname="updateUser($event)"
@access-token="updateToken($event)"
/>
Dans mon Login.vue j'ai :
<form id="login_form">
<span id="error-cant-use-webclipper">Votre environnement ou votre statut ne permet pas
l'utilisation du Webclipper.
<br><br>Veuillez changer de statut ou bien vous connecter via un autre compte</span>
<button
id="btn_se_connecter"
type="submit"
class="vertically-center"
>
<img
src="@/assets/img/outline_account_circle_white_24dp.png"
alt="Account Icon"
>
<span>{{ $i18n("se_connecter") }}</span>
</button>
</form>
Dans mon fichier main.js qui est l'équivalent du popup.js dans mon extension, j'ai ce code :
const formElement = document.querySelector("login_form");
if (formElement) {
formElement.addEventListener("submit", async (ev) => {
ev.preventDefault();
document.querySelector(".timeout").classList.add("chargement");
browser.runtime.sendMessage({
type: "connect",
}).then((response) => console.log(response));
window.close();
});
}
Mais il semble que ce code ne parvienne pas à capturer mon élément puisque lorsque je clique je vois que le submit se fait, donc le preventDefault n'est jamais exécuté, ce qui veut dire qu'il ne rentre jamais dans le code du "if (formElement)"
Bon j'y suis arrivé pour une partie.
Sans mon composant APP.vue j'ai ajouté le listener et au click je suis bien dirigé vers l'authentification sur mon serveur oAuth.
Pour vérifier les données qui étaient conservées j'ai stocké un pseudo token dna sle localStorage.
Et comme l'affichage de Login.vue est conditionné par la valeur de la data "isConnected", une fois de retour sur mon extension après l'authentification oAuth2 j'ai bien mon autre composant Capture.vue qui est chargé au lieu de Login.vue.
beforeMount() {
const loggedOn = localStorage.getItem("Test3");
if (loggedOn) {
this.isConnected = true;
}
},
mounted() {
const formElement = document.querySelector("form");
if (formElement) {
formElement.addEventListener("submit", async (ev) => {
ev.preventDefault();
localStorage.setItem("Test3", "TEST3");
document.querySelector(".timeout").classList.add("chargement");
browser.runtime.sendMessage({
type: "connect",
}).then((response) => console.log(response));
window.close();
});
}
},
Je crois que j'ai compris. Il faut que je gère la com avec le navigateur depuis le composant et non pas depuis le popup.js que j'utilisais avant d'implémenter Vuejs :
beforeMount() {
const loggedOn = localStorage.getItem("Test3");
if (loggedOn) {
this.isConnected = true;
updateMenus(true); -->Ceci permet dans le menu contexte de l'extension de passer l'option "se déconnecter" de disabled à enabled via la fonction updateMenus que j'importe dans mon composant par **import { updateMenus } from "../content_scripts/poplink";**
}
},
mounted() {
const formElement = document.querySelector("form");
if (formElement) {
formElement.addEventListener("submit", async (ev) => {
ev.preventDefault();
localStorage.setItem("Test3", "TEST3");
document.querySelector(".timeout").classList.add("chargement");
browser.runtime.sendMessage({
type: "connect",
}).then((response) => console.log(response));
window.close();
});
}
},