google-oauth-token-generator
Version:
A simple web-based tool to generate Google OAuth access tokens and refresh tokens
461 lines (428 loc) • 18.9 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Google OAuth Access Token Creator</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.input-group {
margin-bottom: 15px;
max-width: 500px;
}
input[type="text"] {
width: 100%;
padding: 8px;
margin-top: 5px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
line-height: 1.5;
height: 36px;
box-sizing: border-box;
}
button {
background-color: #4285f4;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #357abd;
}
.result {
margin-top: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #f8f9fa;
word-break: break-all;
overflow-x: auto;
}
.hidden {
display: none;
}
.instructions {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.instructions ol {
padding-left: 20px;
}
.instructions li {
margin-bottom: 10px;
}
.instructions code {
background: #f0f0f0;
padding: 2px 5px;
border-radius: 3px;
}
.note {
background-color: #fff3cd;
border: 1px solid #ffeeba;
padding: 10px;
border-radius: 4px;
margin: 10px 0;
}
.token-container {
position: relative;
margin-bottom: 20px;
}
.copy-btn {
position: absolute;
top: 0;
right: 0;
padding: 5px 10px;
background: #4285f4;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.copy-btn:hover {
background: #357abd;
}
.token-text {
background: white;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
margin-top: 5px;
white-space: pre-wrap;
word-break: break-all;
}
.password-input-container {
position: relative;
display: flex;
align-items: center;
max-width: 500px;
}
.password-input-container input[type="password"],
.password-input-container input[type="text"] {
flex: 1;
padding: 8px;
margin-top: 5px;
border: 1px solid #ddd;
border-radius: 4px;
width: 100%;
font-size: 14px;
line-height: 1.5;
height: 36px;
box-sizing: border-box;
}
.toggle-password {
position: absolute;
right: 5px;
top: 50%;
transform: translateY(-50%);
margin-top: 2px;
background: none;
border: none;
cursor: pointer;
padding: 5px;
color: #666;
display: flex;
align-items: center;
justify-content: center;
transition: color 0.2s ease;
width: 30px;
height: 30px;
}
.toggle-password:hover {
background: none;
color: #4285f4;
}
.toggle-password svg {
width: 20px;
height: 20px;
fill: currentColor;
}
.eye-icon {
font-size: 16px;
line-height: 1;
}
input[type="text"][list] {
width: 100%;
padding: 8px;
margin-top: 5px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: white;
}
input[type="text"][list]:focus {
outline: none;
border-color: #4285f4;
box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.2);
}
</style>
</head>
<body>
<div class="instructions">
<h2>Setup Instructions</h2>
<ol>
<li>
<strong>Go to Google Cloud Console:</strong>
<br>
<a href="https://console.cloud.google.com" target="_blank">https://console.cloud.google.com</a>
</li>
<li>
<strong>Create a new project or select an existing one:</strong>
<br>
Click on the project selector in the top right corner → "New Project" or select an existing project
</li>
<li>
<strong>Configure OAuth Settings:</strong>
<br>
Go to "APIs & Services" → "OAuth consent screen" and configure:
<ul>
<li>User Type: Select "External"</li>
<li>Publishing Status: Set to "In Production" (Required for public access)</li>
<li>Fill in the required information (App name, User support email, etc.)</li>
<li>Add authorized domains if needed</li>
</ul>
</li>
<li>
<strong>Create credentials:</strong>
<ul>
<li>Go to "APIs & Services" → "Credentials" → "Create Credentials" → "OAuth client ID"</li>
<li>Application type: Select "Web application"</li>
<li>Authorized JavaScript origins: <code id="jsOrigin">Loading...</code></li>
<li>Authorized redirect URIs: <code id="redirectUriExample">Loading...</code></li>
<li>After creating, save both the Client ID and Client Secret - you'll need both</li>
</ul>
</li>
<li>
<strong>Copy your Client ID:</strong>
<br>
Paste the generated Client ID into the form below
</li>
</ol>
<div class="note">
<strong>Important Note:</strong>
<ul>
<li>This application must be run on a web server (e.g., <code id="localExample">Loading...</code>).</li>
<li>The default scope is set to <code>https://www.googleapis.com/auth/userinfo.profile</code>.</li>
<li>Different APIs may require different scopes. Remember to enable the APIs you want to use in Google Cloud Console.</li>
</ul>
</div>
<h3>Common Scopes:</h3>
<ul>
<li><code>https://www.googleapis.com/auth/userinfo.profile</code> - User profile information</li>
<li><code>https://www.googleapis.com/auth/userinfo.email</code> - User email information</li>
<li><code>https://www.googleapis.com/auth/calendar</code> - Google Calendar access</li>
<li><code>https://www.googleapis.com/auth/drive</code> - Full Google Drive access</li>
<li><code>https://www.googleapis.com/auth/gmail.readonly</code> - Gmail read-only access</li>
</ul>
<div class="note">
<strong>Other API Scopes:</strong>
<p>You can find a complete list of scopes for all Google APIs in the official documentation:</p>
<p><a href="https://developers.google.com/identity/protocols/oauth2/scopes" target="_blank">Google OAuth 2.0 Scopes for Google APIs</a></p>
<p><strong>Note:</strong> Some scopes provide access to sensitive data and may require Google verification and app verification.</p>
</div>
</div>
<div class="container">
<h1>Google OAuth Access Token Creator</h1>
<div class="note">
<strong>Redirect URI:</strong> <code id="currentUrl">Loading...</code>
<p>You must add this URL to both "Authorized JavaScript origins" and "Authorized redirect URIs" in Google Cloud Console.</p>
</div>
<div class="input-group">
<label for="clientId">Client ID:</label>
<input type="text" id="clientId" placeholder="Enter your Google Client ID">
</div>
<div class="input-group">
<label for="clientSecret">Client Secret:</label>
<div class="password-input-container">
<input type="password" id="clientSecret" placeholder="Enter your Google Client Secret">
<button type="button" class="toggle-password" onclick="togglePasswordVisibility()" aria-label="Toggle password visibility">
<svg class="eye-show" viewBox="0 0 24 24">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
</svg>
<svg class="eye-hide" viewBox="0 0 24 24" style="display: none;">
<path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/>
</svg>
</button>
</div>
</div>
<div class="input-group">
<label for="scope">Scope:</label>
<input type="text"
id="scope"
list="scopeList"
placeholder="Enter or select the required scope">
<datalist id="scopeList">
<option value="https://www.googleapis.com/auth/userinfo.profile">User Profile Information</option>
<option value="https://www.googleapis.com/auth/userinfo.email">User Email Information</option>
<option value="https://www.googleapis.com/auth/calendar">Google Calendar Access</option>
<option value="https://www.googleapis.com/auth/drive">Google Drive Full Access</option>
<option value="https://www.googleapis.com/auth/gmail.readonly">Gmail Read-only Access</option>
<option value="https://www.googleapis.com/auth/cloud-platform">Google Cloud Platform Full Access</option>
<option value="https://www.googleapis.com/auth/cloud-platform.read-only">Google Cloud Platform Read-only Access</option>
<option value="https://www.googleapis.com/auth/youtube">YouTube Account Management</option>
<option value="https://www.googleapis.com/auth/youtube.readonly">YouTube Read-only Access</option>
<option value="https://www.googleapis.com/auth/youtube.upload">YouTube Video Management</option>
<option value="https://www.googleapis.com/auth/yt-analytics.readonly">YouTube Analytics Access</option>
<option value="https://www.googleapis.com/auth/youtube.force-ssl">YouTube Force SSL Access</option>
<option value="https://www.googleapis.com/auth/admob.readonly">AdMob Read-only Access</option>
<option value="https://www.googleapis.com/auth/admob.report">AdMob Reporting Access</option>
</datalist>
</div>
<button onclick="initiateOAuth()">Get Access Token</button>
<div id="result" class="result hidden">
<div class="token-container">
<h3>Access Token: <button onclick="copyToken()" class="copy-btn">Copy</button></h3>
<div id="accessToken" class="token-text"></div>
</div>
<div class="token-container">
<h3>Refresh Token: <button onclick="copyRefreshToken()" class="copy-btn">Copy</button></h3>
<div id="refreshToken" class="token-text"></div>
</div>
<div class="token-container">
<h3>Token Info: <button onclick="copyTokenInfo()" class="copy-btn">Copy</button></h3>
<div id="tokenInfo" class="token-text"></div>
</div>
</div>
</div>
<script>
// OAuth configuration
const redirectUri = window.location.origin;
// Display current URL in all places
function updateUrls() {
const elements = ['currentUrl', 'jsOrigin', 'redirectUriExample', 'localExample'];
elements.forEach(id => {
const element = document.getElementById(id);
if (element) {
element.textContent = redirectUri;
}
});
}
// Update URLs immediately
updateUrls();
function initiateOAuth() {
const clientId = document.getElementById('clientId').value;
const clientSecret = document.getElementById('clientSecret').value;
const scope = document.getElementById('scope').value;
if (!clientId) {
alert('Please enter your Client ID');
return;
}
// Store credentials in the state parameter
const state = btoa(JSON.stringify({ clientId, clientSecret }));
const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?
client_id=${encodeURIComponent(clientId)}&
redirect_uri=${encodeURIComponent(redirectUri)}&
response_type=code&
access_type=offline&
prompt=consent&
state=${encodeURIComponent(state)}&
scope=${encodeURIComponent(scope)}&
include_granted_scopes=true`;
window.location.href = authUrl.replace(/\s/g, '');
}
// Copy functions
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
alert('Copied!');
}).catch(err => {
console.error('Copy error:', err);
alert('Copy failed');
});
}
function copyToken() {
const token = document.getElementById('accessToken').textContent;
copyToClipboard(token);
}
function copyRefreshToken() {
const token = document.getElementById('refreshToken').textContent;
copyToClipboard(token);
}
function copyTokenInfo() {
const info = document.getElementById('tokenInfo').textContent;
copyToClipboard(info);
}
// Handle the OAuth callback
window.onload = function() {
// Display current URL
updateUrls();
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
if (code && state) {
try {
// Retrieve credentials from state parameter
const credentials = JSON.parse(atob(state));
const clientId = credentials.clientId;
const clientSecret = credentials.clientSecret;
const tokenEndpoint = 'https://oauth2.googleapis.com/token';
const tokenRequest = {
code: code,
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectUri,
grant_type: 'authorization_code'
};
fetch(tokenEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(tokenRequest)
})
.then(response => response.json())
.then(data => {
document.getElementById('result').classList.remove('hidden');
document.getElementById('accessToken').textContent = data.access_token;
document.getElementById('refreshToken').textContent = data.refresh_token || 'No refresh token provided';
// Fetch token info
return fetch(`https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=${data.access_token}`);
})
.then(response => response.json())
.then(data => {
document.getElementById('tokenInfo').textContent = JSON.stringify(data, null, 2);
})
.catch(error => {
console.error('Error:', error);
alert('Error exchanging code for tokens. Check the console for details.');
});
} catch (error) {
console.error('Error parsing state:', error);
alert('Error retrieving credentials. Please try again.');
}
}
};
function togglePasswordVisibility() {
const input = document.getElementById('clientSecret');
const showIcon = document.querySelector('.eye-show');
const hideIcon = document.querySelector('.eye-hide');
if (input.type === 'password') {
input.type = 'text';
showIcon.style.display = 'none';
hideIcon.style.display = 'block';
} else {
input.type = 'password';
showIcon.style.display = 'block';
hideIcon.style.display = 'none';
}
}
</script>
</body>
</html>