tfrere HF Staff commited on
Commit
22665fb
·
verified ·
1 Parent(s): 3f84555

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +108 -18
index.html CHANGED
@@ -1,19 +1,109 @@
1
- <!doctype html>
2
  <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
  <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Hugging Face OAuth Example</title>
6
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
7
+ <style>
8
+ body { font-family: sans-serif; background: #fafafd; color: #222; }
9
+ .card { max-width: 400px; margin: 2rem auto; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px #0001; padding: 2rem; }
10
+ #status { margin-top: 1rem; word-break: break-all; }
11
+ button, img { margin-top: 1rem; }
12
+ pre { background: #eee; padding: 1em; border-radius: 4px; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <div class="card">
17
+ <h1>Sign in with Hugging Face (vanilla JS)</h1>
18
+ <p>
19
+ This example demonstrates how to add a "Sign in with HF" button to your Space using only HTML and plain JavaScript.<br>
20
+ No external dependencies or build step needed.
21
+ </p>
22
+ <img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-xl-dark.svg"
23
+ alt="Sign in with Hugging Face" id="login-hf-btn" style="cursor:pointer;max-width:100%;">
24
+ <button id="signout" style="display:none;">Sign out</button>
25
+ <div id="status"></div>
26
+ <pre id="userinfo" style="display:none"></pre>
27
+ </div>
28
+ <script>
29
+ const CLIENT_ID = window.huggingface?.variables?.OAUTH_CLIENT_ID;
30
+ const REDIRECT_URI = window.location.origin + window.location.pathname; // or your custom callback
31
+ const HF_OAUTH_URL = 'https://huggingface.co/oauth/authorize';
32
+ const HF_TOKEN_URL = 'https://huggingface.co/oauth/token';
33
+
34
+ // Show login button and handle click
35
+ document.getElementById('login-hf-btn').onclick = function () {
36
+ const state = Math.random().toString(36).slice(2);
37
+ localStorage.setItem('hf_oauth_state', state);
38
+ const url = `${HF_OAUTH_URL}?client_id=${CLIENT_ID}` +
39
+ `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
40
+ `&response_type=code&scope=openid%20profile&state=${state}`;
41
+ window.location = url;
42
+ };
43
+
44
+ // Sign out logic
45
+ document.getElementById('signout').onclick = function () {
46
+ localStorage.removeItem('hf_oauth_state');
47
+ localStorage.removeItem('hf_oauth_token');
48
+ localStorage.removeItem('hf_oauth_userinfo');
49
+ window.location.href = window.location.pathname;
50
+ };
51
+
52
+ // Handle OAuth callback
53
+ window.onload = async function () {
54
+ const params = new URLSearchParams(window.location.search);
55
+ // If redirected back after OAuth
56
+ if (params.has('code') && params.has('state')) {
57
+ const state = params.get('state');
58
+ if (state !== localStorage.getItem('hf_oauth_state')) {
59
+ document.getElementById('status').textContent = 'Invalid state, possible CSRF detected.';
60
+ return;
61
+ }
62
+ const code = params.get('code');
63
+ const body = new URLSearchParams({
64
+ client_id: CLIENT_ID,
65
+ grant_type: 'authorization_code',
66
+ code: code,
67
+ redirect_uri: REDIRECT_URI
68
+ });
69
+ document.getElementById('status').textContent = 'Exchanging code for token...';
70
+ const resp = await fetch(HF_TOKEN_URL, {
71
+ method: 'POST',
72
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
73
+ body
74
+ });
75
+ const data = await resp.json();
76
+ if (data.access_token) {
77
+ localStorage.setItem('hf_oauth_token', data.access_token);
78
+ document.getElementById('status').textContent = 'Logged in!';
79
+ // Fetch userinfo
80
+ const respUser = await fetch('https://huggingface.co/oauth/userinfo', {
81
+ headers: { Authorization: `Bearer ${data.access_token}` }
82
+ });
83
+ const userinfo = await respUser.json();
84
+ localStorage.setItem('hf_oauth_userinfo', JSON.stringify(userinfo, null, 2));
85
+ document.getElementById('userinfo').style.display = '';
86
+ document.getElementById('userinfo').textContent = JSON.stringify(userinfo, null, 2);
87
+ document.getElementById('signout').style.display = '';
88
+ document.getElementById('login-hf-btn').style.display = 'none';
89
+ // Clean up URL
90
+ window.history.replaceState({}, '', window.location.pathname);
91
+ } else {
92
+ document.getElementById('status').textContent = 'OAuth failed: ' + JSON.stringify(data);
93
+ }
94
+ return;
95
+ }
96
+ // If already logged in, show info
97
+ const token = localStorage.getItem('hf_oauth_token');
98
+ const userinfo = localStorage.getItem('hf_oauth_userinfo');
99
+ if (token && userinfo) {
100
+ document.getElementById('status').textContent = 'Already logged in!';
101
+ document.getElementById('userinfo').style.display = '';
102
+ document.getElementById('userinfo').textContent = userinfo;
103
+ document.getElementById('signout').style.display = '';
104
+ document.getElementById('login-hf-btn').style.display = 'none';
105
+ }
106
+ };
107
+ </script>
108
+ </body>
109
+ </html>