thibaud frere commited on
Commit
69b83cc
·
1 Parent(s): 4563b43
Files changed (1) hide show
  1. index.html +72 -96
index.html CHANGED
@@ -3,131 +3,107 @@
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width" />
6
- <title>HF OAuth Example</title>
 
7
  <style>
8
- body { font-family: sans-serif; padding: 2rem; max-width: 600px; margin: 0 auto; }
9
- button { padding: 0.5rem 1rem; margin: 0.5rem 0; cursor: pointer; }
10
- #status { margin: 1rem 0; color: #666; }
11
- pre { background: #f5f5f5; padding: 1rem; border-radius: 4px; overflow-x: auto; }
 
 
12
  </style>
13
  </head>
14
  <body>
15
- <h1>HF OAuth Example</h1>
16
-
17
- <img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-xl-dark.svg"
18
- alt="Sign in with Hugging Face" id="signin" style="cursor:pointer;display:none;max-width:300px;">
19
-
20
- <button id="signout" style="display:none;">Sign out</button>
21
- <div id="status"></div>
22
- <pre id="userinfo" style="display:none;"></pre>
23
- <script>
24
- // Use environment variables provided by HF Spaces OAuth
25
- const CLIENT_ID = window.OAUTH_CLIENT_ID || 'e0906ea6-519f-4aa0-a128-9b7df044e477';
26
- const CLIENT_SECRET = window.OAUTH_CLIENT_SECRET;
 
 
 
 
 
 
 
 
 
27
  const REDIRECT_URI = window.location.origin + window.location.pathname;
 
 
28
 
 
29
  function showLoggedIn(userinfo) {
30
  document.getElementById('signin').style.display = 'none';
31
- document.getElementById('signout').style.display = 'block';
32
  document.getElementById('status').textContent = 'Logged in!';
33
- document.getElementById('userinfo').style.display = 'block';
34
  document.getElementById('userinfo').textContent = userinfo;
35
  }
36
-
37
  function showLoggedOut() {
38
- document.getElementById('signin').style.display = 'block';
39
  document.getElementById('signout').style.display = 'none';
40
  document.getElementById('status').textContent = '';
41
  document.getElementById('userinfo').style.display = 'none';
 
42
  }
43
 
44
- document.getElementById('signin').onclick = function () {
45
- const state = Math.random().toString(36).slice(2);
46
- localStorage.setItem('hf_oauth_state', state);
47
- // Use official OAuth URL as per documentation
48
- const url = `https://huggingface.co/oauth/authorize?redirect_uri=${encodeURIComponent(REDIRECT_URI)}&scope=openid%20profile&client_id=${CLIENT_ID}&state=${state}`;
49
- // Open in new tab to avoid iframe issues
50
- window.open(url, '_blank');
 
 
51
  };
52
 
 
53
  document.getElementById('signout').onclick = function () {
54
- localStorage.clear();
 
 
55
  showLoggedOut();
56
  window.history.replaceState({}, '', window.location.pathname);
57
  };
58
 
 
59
  window.onload = async function () {
60
- const params = new URLSearchParams(window.location.search);
61
-
62
- if (params.has('code') && params.has('state')) {
63
- const state = params.get('state');
64
- if (state !== localStorage.getItem('hf_oauth_state')) {
65
- document.getElementById('status').textContent = 'Invalid state parameter';
66
- return;
67
- }
68
-
69
- const code = params.get('code');
70
- document.getElementById('status').textContent = 'Exchanging code for access token...';
71
 
72
- try {
73
- // Official token exchange as per HF documentation
74
- const tokenResponse = await fetch('https://huggingface.co/oauth/token', {
75
- method: 'POST',
76
- headers: {
77
- 'Content-Type': 'application/x-www-form-urlencoded',
78
- 'Authorization': `Basic ${btoa(CLIENT_ID + ':' + (CLIENT_SECRET || ''))}`
79
- },
80
- body: new URLSearchParams({
81
- grant_type: 'authorization_code',
82
- code: code,
83
- redirect_uri: REDIRECT_URI,
84
- client_id: CLIENT_ID
85
- })
86
- });
87
-
88
- if (!tokenResponse.ok) {
89
- throw new Error(`Token exchange failed: ${tokenResponse.status}`);
90
- }
91
-
92
- const tokenData = await tokenResponse.json();
93
-
94
- if (tokenData.access_token) {
95
- // Get user info with access token
96
- document.getElementById('status').textContent = 'Getting user information...';
97
-
98
- const userResponse = await fetch('https://huggingface.co/oauth/userinfo', {
99
- headers: {
100
- 'Authorization': `Bearer ${tokenData.access_token}`
101
- }
102
- });
103
-
104
- if (userResponse.ok) {
105
- const userInfo = await userResponse.json();
106
- const userInfoStr = JSON.stringify(userInfo, null, 2);
107
- localStorage.setItem('hf_oauth_token', tokenData.access_token);
108
- localStorage.setItem('hf_oauth_userinfo', userInfoStr);
109
- showLoggedIn(userInfoStr);
110
- } else {
111
- throw new Error('Failed to get user info');
112
- }
113
  } else {
114
- throw new Error('No access token received');
115
  }
116
-
117
- window.history.replaceState({}, '', window.location.pathname);
118
- } catch (error) {
119
- console.error('OAuth error:', error);
120
- document.getElementById('status').textContent = 'Error: ' + error.message;
121
- showLoggedOut();
122
  }
123
- return;
124
- }
125
-
126
- // Check if already logged in
127
- const userinfo = localStorage.getItem('hf_oauth_userinfo');
128
- if (userinfo) {
129
- showLoggedIn(userinfo);
130
- } else {
131
  showLoggedOut();
132
  }
133
  };
 
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width" />
6
+ <title>OAuth in a static Space (Vanilla JS)</title>
7
+ <link rel="stylesheet" href="style.css" />
8
  <style>
9
+ body { font-family: sans-serif; background: white; color: #222; }
10
+ .card { max-width: 420px; margin: 2rem auto 0 auto; background: #fff; border-radius: 16px; box-shadow: 0 2px 8px #0001; padding: 2rem; }
11
+ #status { margin-top: 1rem; word-break: break-all; color: #b00; }
12
+ button, img { margin-top: 1rem; }
13
+ pre { background: #eee; padding: 1em; border-radius: 4px; margin-top: 1rem; }
14
+ #signout { margin-left: 0; }
15
  </style>
16
  </head>
17
  <body>
18
+ <div class="card">
19
+ <h1>OAuth in a static Space (Vanilla JS)</h1>
20
+ <p>
21
+ This is a demonstration of the Hugging Face OAuth flow in a <b>static Space</b> using only vanilla JS.<br>
22
+ No external libraries are needed – just copy this HTML file in your Space!
23
+
24
+ After clicking "Signin with HF", you will be redirected to this space and the access token + user info will be displayed.
25
+ </p>
26
+ <img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-xl-dark.svg"
27
+ alt="Sign in with Hugging Face" id="signin" style="cursor:pointer;display:none;max-width:100%;">
28
+ <button id="signout" style="display:none;">Sign out</button>
29
+ <div id="status"></div>
30
+ <pre id="userinfo" style="display:none"></pre>
31
+ </div>
32
+ <script type="module">
33
+ // Import de la librairie HF pour une méthode plus simple et fiable
34
+ import { oauthLoginUrl, oauthHandleRedirectIfPresent } from "https://cdn.skypack.dev/@huggingface/hub";
35
+
36
+ // Fallback pour les variables OAuth si on utilise la méthode manuelle
37
+ const CLIENT_ID = window.OAUTH_CLIENT_ID || window.huggingface?.space?.oauth?.clientId;
38
+ const CLIENT_SECRET = window.OAUTH_CLIENT_SECRET || window.huggingface?.space?.oauth?.clientSecret;
39
  const REDIRECT_URI = window.location.origin + window.location.pathname;
40
+ const HF_OAUTH_URL = 'https://huggingface.co/oauth/authorize';
41
+ const HF_TOKEN_URL = 'https://huggingface.co/oauth/token';
42
 
43
+ // Helper pour afficher l'état et les infos utilisateur
44
  function showLoggedIn(userinfo) {
45
  document.getElementById('signin').style.display = 'none';
46
+ document.getElementById('signout').style.display = '';
47
  document.getElementById('status').textContent = 'Logged in!';
48
+ document.getElementById('userinfo').style.display = '';
49
  document.getElementById('userinfo').textContent = userinfo;
50
  }
 
51
  function showLoggedOut() {
52
+ document.getElementById('signin').style.display = '';
53
  document.getElementById('signout').style.display = 'none';
54
  document.getElementById('status').textContent = '';
55
  document.getElementById('userinfo').style.display = 'none';
56
+ document.getElementById('userinfo').textContent = '';
57
  }
58
 
59
+ // Sign in button - utilise la méthode recommandée par HF
60
+ document.getElementById('signin').onclick = async function () {
61
+ try {
62
+ const loginUrl = await oauthLoginUrl();
63
+ window.location.href = loginUrl;
64
+ } catch (error) {
65
+ console.error('Erreur lors de la génération de l\'URL de login:', error);
66
+ document.getElementById('status').textContent = 'Erreur: Impossible de générer l\'URL de connexion. Vérifiez la configuration OAuth.';
67
+ }
68
  };
69
 
70
+ // Sign out button
71
  document.getElementById('signout').onclick = function () {
72
+ localStorage.removeItem('hf_oauth_token');
73
+ localStorage.removeItem('hf_oauth_userinfo');
74
+ localStorage.removeItem('hf_oauth_state');
75
  showLoggedOut();
76
  window.history.replaceState({}, '', window.location.pathname);
77
  };
78
 
79
+ // Handle OAuth callback - utilise la méthode recommandée par HF
80
  window.onload = async function () {
81
+ try {
82
+ // Utilise la fonction HF pour gérer le redirect OAuth
83
+ const oauthResult = await oauthHandleRedirectIfPresent();
 
 
 
 
 
 
 
 
84
 
85
+ if (oauthResult) {
86
+ // L'utilisateur vient de se connecter
87
+ console.log('OAuth result:', oauthResult);
88
+ const userinfoStr = JSON.stringify(oauthResult.userInfo, null, 2);
89
+ localStorage.setItem('hf_oauth_token', oauthResult.accessToken);
90
+ localStorage.setItem('hf_oauth_userinfo', userinfoStr);
91
+ showLoggedIn(userinfoStr);
92
+ // Clean up URL
93
+ window.history.replaceState({}, '', window.location.pathname);
94
+ } else {
95
+ // Vérifier si l'utilisateur est déjà connecté
96
+ const token = localStorage.getItem('hf_oauth_token');
97
+ const userinfo = localStorage.getItem('hf_oauth_userinfo');
98
+ if (token && userinfo) {
99
+ showLoggedIn(userinfo);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  } else {
101
+ showLoggedOut();
102
  }
 
 
 
 
 
 
103
  }
104
+ } catch (error) {
105
+ console.error('Erreur OAuth:', error);
106
+ document.getElementById('status').textContent = 'Erreur lors de la gestion OAuth: ' + error.message;
 
 
 
 
 
107
  showLoggedOut();
108
  }
109
  };