File size: 5,868 Bytes
22665fb 3f84555 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 22665fb f91a47c 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 129 130 131 |
<!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: #fafafd; color: #222; }
.card { max-width: 420px; margin: 2rem auto 0 auto; background: #fff; border-radius: 8px; 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!
</p>
<p>
Click "Sign in with HF" to start the authentication flow.<br>
After authenticating, your access token and user info will be displayed below.<br>
<i>(Tokens are only stored locally in your browser and never sent anywhere else.)</i>
</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> |