Введение в аутентификацию с использованием Google Apps Script для веб-сайтов
Зачем использовать Google Apps Script для аутентификации?
Google Apps Script (GAS) предоставляет удобный способ для создания веб-приложений, использующих сервисы Google. Он позволяет быстро разработать систему аутентификации, особенно если уже используется инфраструктура Google (например, Google Sheets для хранения данных, Google Cloud Platform для расширенных возможностей). GAS избавляет от необходимости развертывания сложных серверных решений, предлагая масштабируемую и надежную среду выполнения.
Основные понятия: OAuth 2.0 и Apps Script
OAuth 2.0 – это стандарт авторизации, позволяющий пользователям предоставлять сторонним приложениям доступ к своим ресурсам без передачи учетных данных. GAS тесно интегрирован с OAuth 2.0, что упрощает процесс аутентификации через Google-аккаунт.
В Apps Script авторизация используется для доступа к сервисам Google (Sheets, Docs, Drive и т.д.) от имени пользователя. Скрипт запрашивает разрешения (scopes) у пользователя, и, если пользователь дает согласие, скрипт получает токен доступа.
Обзор различных методов аутентификации
Существует несколько способов организовать вход на сайт с использованием Google Apps Script:
- Базовая аутентификация: Проверка логина и пароля, хранящихся, например, в Google Sheets.
- Google Sign-In: Использование Google-аккаунта пользователя для аутентификации (OAuth 2.0).
- Сторонние сервисы аутентификации: Интеграция с внешними провайдерами идентификации (например, Auth0, Firebase Authentication) через API.
Реализация базовой аутентификации с помощью Google Apps Script и Google Sheets
Создание Google Sheet для хранения учетных данных
Создайте Google Sheet с двумя столбцами: «Логин» и «Пароль». Заполните его учетными данными пользователей. Не храните пароли в открытом виде! Используйте хеширование (см. далее).
Написание скрипта Apps Script для проверки учетных данных
/**
* Функция для проверки логина и пароля.
*
* @param {string} login Логин пользователя.
* @param {string} password Пароль пользователя.
* @return {boolean} True, если учетные данные верны, иначе false.
*/
function authenticate(login, password) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName("Users"); // Замените "Users" на имя вашего листа
const data = sheet.getDataRange().getValues();
// Пропускаем строку заголовков
for (let i = 1; i < data.length; i++) {
const userLogin = data[i][0];
const userPassword = data[i][1];
// Сравниваем логин и пароль (ВНИМАНИЕ: пароли нужно хешировать!)
if (login === userLogin && password === userPassword) { //Никогда не сравнивайте пароли в открытом виде!
return true;
}
}
return false;
}
Развертывание скрипта как веб-приложения
- В редакторе Apps Script выберите Публикация -> Развернуть как веб-приложение…
- Выберите Кто имеет доступ: -> Все
- Нажмите Развернуть.
- Скопируйте URL веб-приложения. Это URL, который вы будете использовать в HTML-форме.
Создание HTML-формы для ввода логина и пароля
<!DOCTYPE html>
<html>
<head>
<title>Login Form</title>
</head>
<body>
<h1>Login</h1>
<form id="loginForm">
<label for="login">Login:</label><br>
<input type="text" id="login" name="login"><br><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br><br>
<button type="button" onclick="submitForm()">Login</button>
</form>
<script>
function submitForm() {
const login = document.getElementById("login").value;
const password = document.getElementById("password").value;
// Замените YOUR_WEB_APP_URL на URL вашего веб-приложения
const url = "YOUR_WEB_APP_URL?login=" + encodeURIComponent(login) + "&password=" + encodeURIComponent(password);
fetch(url)
.then(response => response.text())
.then(data => {
if (data === "true") {
alert("Login successful!");
// Перенаправление на защищенную страницу
window.location.href = "/secured_page";
} else {
alert("Login failed.");
}
});
}
</script>
</body>
</html>
ВНИМАНИЕ: Этот пример небезопасен для production-использования, так как передает пароль в открытом виде. Всегда используйте HTTPS и хеширование паролей.
Реализация аутентификации с использованием сервиса Google Sign-In
Настройка проекта Google Cloud для Google Sign-In
- Перейдите в Google Cloud Console.
- Создайте новый проект или выберите существующий.
- Включите API Google Sign-In API.
- Создайте учетные данные (credentials) типа Client ID для веб-приложения. Укажите разрешенные источники JavaScript (origins) и URI перенаправления.
Интеграция Google Sign-In в HTML-страницу
<!DOCTYPE html>
<html>
<head>
<title>Google Sign-In</title>
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<a href="#" onclick="signOut();">Sign out</a>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script>
function onSignIn(googleUser) {
const profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId()); // Не отправляйте на сервер!
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
const id_token = googleUser.getIdToken();
console.log("ID Token: " + id_token);
// Отправьте id_token на ваш Apps Script для верификации.
sendTokenToBackend(id_token);
}
function signOut() {
const auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
});
}
function sendTokenToBackend(token) {
// Замените YOUR_WEB_APP_URL на URL вашего веб-приложения
const url = "YOUR_WEB_APP_URL?id_token=" + encodeURIComponent(token);
fetch(url)
.then(response => response.text())
.then(data => {
if (data === "success") {
alert("Authentication successful!");
window.location.href = "/secured_page";
} else {
alert("Authentication failed.");
}
});
}
</script>
</body>
</html>
Получение и верификация токена пользователя на сервере (Apps Script)
/**
* Функция для верификации токена Google ID.
*
* @param {string} id_token Токен Google ID.
* @return {string} "success", если токен верен, иначе "error".
*/
function verifyToken(id_token) {
try {
const ticket = Auth.verifyIdToken(id_token, CLIENT_ID); // Замените CLIENT_ID на ваш Client ID из Google Cloud Console.
const payload = ticket.getPayload();
const userId = payload['sub']; // Google User ID
const email = payload['email'];
Logger.log("User ID: " + userId);
Logger.log("Email: " + email);
// Здесь можно сохранить userId или email в Google Sheet или другом хранилище.
return "success";
} catch (e) {
Logger.log("Error verifying token: " + e);
return "error";
}
}
/**
* doGet function для обработки запросов.
*/
function doGet(e) {
const id_token = e.parameter.id_token;
if (id_token) {
return ContentService.createTextOutput(verifyToken(id_token));
} else {
return ContentService.createTextOutput("error");
}
}
Важно: Не забудьте установить библиотеку Google Auth Library в редакторе Apps Script. Перейдите в Ресурсы -> Библиотеки и добавьте библиотеку с ID: 1B7FSdrN5nZreW4XillUY5 hisW4OgaDLkAIa5R7AG7hcgyMwSJC65GEu
.
Обработка успешной аутентификации и перенаправление пользователя
После успешной верификации токена, перенаправьте пользователя на защищенную страницу вашего сайта, используя window.location.href
в JavaScript.
Улучшение безопасности и пользовательского опыта
Хранение паролей с использованием хеширования (bcrypt, scrypt)
Никогда не храните пароли в открытом виде. Используйте криптографические хеш-функции, такие как bcrypt или scrypt, чтобы необратимо преобразовать пароль в хеш. При аутентификации сравнивайте хеш введенного пароля с хешем, хранящимся в базе данных.
К сожалению, Apps Script не имеет встроенной поддержки bcrypt или scrypt. Можно использовать сторонние библиотеки, доступные через UrlFetchApp, или реализовать более простые (но менее безопасные) хеш-функции, такие как SHA-256.
Реализация функциональности восстановления пароля
Предоставьте пользователям возможность восстановить забытый пароль. Этот процесс обычно включает отправку письма со ссылкой для сброса пароля на зарегистрированный адрес электронной почты.
Использование сессий для сохранения состояния аутентификации
Используйте сессии, чтобы запомнить, что пользователь аутентифицирован. Это позволит избежать повторной аутентификации на каждой странице. В Apps Script можно использовать Script Properties или PropertiesService для хранения данных сессии.
Защита от распространенных атак (CSRF, XSS)
- CSRF (Cross-Site Request Forgery): Предотвратите подделку межсайтовых запросов, используя токены CSRF. При каждой отправке формы генерируйте случайный токен и проверяйте его на сервере.
- XSS (Cross-Site Scripting): Фильтруйте и экранируйте пользовательский ввод, чтобы предотвратить выполнение вредоносного кода в браузере пользователя.
Заключение и дальнейшие шаги
Сравнение различных методов аутентификации
- Базовая аутентификация: Проста в реализации, но менее безопасна. Подходит для простых веб-приложений, где безопасность не является критической.
- Google Sign-In: Более безопасна и удобна для пользователей, у которых уже есть Google-аккаунт. Требует настройки проекта Google Cloud.
- Сторонние сервисы аутентификации: Предоставляют расширенные возможности, такие как двухфакторная аутентификация и интеграция с различными провайдерами идентификации. Требуют дополнительных затрат и настройки.
Рекомендации по выбору оптимального подхода для вашего веб-сайта
Выбор метода аутентификации зависит от требований вашего веб-сайта. Если вам нужна простая аутентификация и у вас ограниченные ресурсы, базовая аутентификация может быть подходящим вариантом. Если вам нужна более безопасная и удобная аутентификация, используйте Google Sign-In. Если вам нужны расширенные возможности, рассмотрите возможность использования сторонних сервисов аутентификации.