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>