File size: 5,722 Bytes
22665fb 3f84555 22665fb f91a47c 69b83cc 22665fb 69b83cc 22665fb 69b83cc ea67b4c f91a47c 69b83cc 22665fb 69b83cc f91a47c 9b42726 69b83cc f91a47c 69b83cc f91a47c 69b83cc f91a47c 69b83cc f91a47c ea67b4c 22665fb 69b83cc 22665fb 69b83cc 9b42726 22665fb ea67b4c 22665fb ea67b4c 69b83cc ea67b4c 22665fb ea67b4c 9b42726 22665fb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<!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> |