thibaud frere
fix
ea67b4c
raw
history blame
5.72 kB
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>OAuth in a static Space (Vanilla JS)</title>
<link rel="stylesheet" href="style.css" />
<style>
body { font-family: sans-serif; background: white; color: #222; }
.card { max-width: 420px; margin: 2rem auto 0 auto; background: #fff; border-radius: 16px; box-shadow: 0 2px 8px #0001; padding: 2rem; }
#status { margin-top: 1rem; word-break: break-all; color: #b00; }
button, img { margin-top: 1rem; }
pre { background: #eee; padding: 1em; border-radius: 4px; margin-top: 1rem; }
#signout { margin-left: 0; }
</style>
</head>
<body>
<div class="card">
<h1>OAuth in a static Space (Vanilla JS)</h1>
<p>
This is a demonstration of the Hugging Face OAuth flow in a <b>static Space</b> using only vanilla JS.<br>
No external libraries are needed – just copy this HTML file in your Space!
After clicking "Signin with HF", you will be redirected to this space and the access token + user info will be displayed.
</p>
<img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-xl-dark.svg"
alt="Sign in with Hugging Face" id="signin" style="cursor:pointer;display:none;max-width:100%;">
<button id="signout" style="display:none;">Sign out</button>
<div id="status"></div>
<pre id="userinfo" style="display:none"></pre>
</div>
<script>
// Utiliser le client_id injecté par Hugging Face dans l'environnement du Space
const CLIENT_ID = window.huggingface?.variables?.OAUTH_CLIENT_ID;
const REDIRECT_URI = window.location.origin + window.location.pathname;
const HF_OAUTH_URL = 'https://huggingface.co/oauth/authorize';
const HF_TOKEN_URL = 'https://huggingface.co/oauth/token';
// Helper pour afficher l'état et les infos utilisateur
function showLoggedIn(userinfo) {
document.getElementById('signin').style.display = 'none';
document.getElementById('signout').style.display = '';
document.getElementById('status').textContent = 'Logged in!';
document.getElementById('userinfo').style.display = '';
document.getElementById('userinfo').textContent = userinfo;
}
function showLoggedOut() {
document.getElementById('signin').style.display = '';
document.getElementById('signout').style.display = 'none';
document.getElementById('status').textContent = '';
document.getElementById('userinfo').style.display = 'none';
document.getElementById('userinfo').textContent = '';
}
// Sign in button
document.getElementById('signin').onclick = function () {
const state = Math.random().toString(36).slice(2);
localStorage.setItem('hf_oauth_state', state);
const url = `${HF_OAUTH_URL}?client_id=${CLIENT_ID}` +
`&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
`&response_type=code&scope=openid%20profile&state=${state}&prompt=consent`;
window.location = url;
};
// Sign out button
document.getElementById('signout').onclick = function () {
localStorage.removeItem('hf_oauth_token');
localStorage.removeItem('hf_oauth_userinfo');
localStorage.removeItem('hf_oauth_state');
showLoggedOut();
window.history.replaceState({}, '', window.location.pathname);
};
// Handle OAuth callback
window.onload = async function () {
// If returning from OAuth redirect
const params = new URLSearchParams(window.location.search);
if (params.has('code') && params.has('state')) {
const state = params.get('state');
if (state !== localStorage.getItem('hf_oauth_state')) {
document.getElementById('status').textContent = 'Invalid state, possible CSRF detected.';
return;
}
const code = params.get('code');
const body = new URLSearchParams({
client_id: CLIENT_ID,
grant_type: 'authorization_code',
code: code,
redirect_uri: REDIRECT_URI
});
document.getElementById('status').textContent = 'Exchanging code for token...';
const resp = await fetch(HF_TOKEN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body
});
const data = await resp.json();
if (data.access_token) {
localStorage.setItem('hf_oauth_token', data.access_token);
// Fetch userinfo
const respUser = await fetch('https://huggingface.co/oauth/userinfo', {
headers: { Authorization: `Bearer ${data.access_token}` }
});
const userinfo = await respUser.json();
const userinfoStr = JSON.stringify(userinfo, null, 2);
localStorage.setItem('hf_oauth_userinfo', userinfoStr);
showLoggedIn(userinfoStr);
// Clean up URL
window.history.replaceState({}, '', window.location.pathname);
} else {
document.getElementById('status').textContent = 'OAuth failed: ' + JSON.stringify(data);
showLoggedOut();
}
return;
}
// Already logged in?
const token = localStorage.getItem('hf_oauth_token');
const userinfo = localStorage.getItem('hf_oauth_userinfo');
if (token && userinfo) {
showLoggedIn(userinfo);
} else {
showLoggedOut();
}
};
</script>
</body>
</html>