Доступ к данным oauth выдача новых oauth токенов что это
Тонкости авторизации: обзор технологии OAuth 2.0
Информационная система Dodo IS состоит из 44 различных сервисов, таких как Трекер, Кассы ресторана или Базы знаний и многих других. Чтобы не отвлекаться на несколько аккаунтов, 3 года назад мы написали сервис Auth для реализации сквозной аутентификации, а сейчас пишем уже вторую версию, в основе которого лежит стандарт авторизации OAuth 2.0. Этот стандарт довольно сложный, но если у вас сложная архитектура с множеством сервисов, то OAuth 2.0 вам пригодится при разработке своего сервиса аутентификации. В этой статье я постарался рассказать о стандарте максимально просто и понятно, чтобы вы сэкономили время на его изучение.
Задача Auth
Проблема авторизации в десятках сервисов встречалась ещё несколько лет назад — в начале «эпохи распила монолита». Эту проблему решили новым сервисом, который назвали – Auth. Он помог реализовать бесшовную аутентификацию в различных сервисах и перенести данные о пользователях в отдельные базы данных.
У сервиса Auth есть три основные задачи:
Проблемы
Первая версия Auth — часть монолита. Он использует свой собственный протокол общения с сервисами. Такая «схема» была необходима в тот момент, но за несколько лет работы проявились проблемы.
Auth — часть монолита. Следовательно, сервис привязан к релизному циклу, что лишает возможности независимой разработки и деплоя. Кроме того, придется разворачивать весь монолит, если захотелось развернуть Auth, например, при масштабировании сервиса.
Dodo IS зависит от Auth. В старой реализации внешние сервисы обращаются к Auth при каждом действии пользователя, чтобы валидировать данные о нём. Настолько сильная привязка может привести к остановке работы всей Dodo IS, если Auth «приляжет» по какой-то причине.
Auth зависит от Redis. Притом достаточно сильно — неисправность работы Redis’а приведёт к падению Auth’а. Мы используем Azure Redis, для которого заявленный SLA 99,9%. Это значит, что сервис может быть недоступен до 44 минут в месяц. Такие простои не позволительны.
Текущая реализация Auth использует свой протокол аутентификации, не опираясь на стандарты. В большинстве своих сервисов мы используем C# (если говорим о backend) и у нас нет проблем с поддержкой библиотеки для нашего протокола. Но если вдруг появятся сервисы на Python, Go или Rust, разработка и поддержка библиотек под эти языки потребует дополнительных затрат времени и принесет дополнительные сложности.
Текущий Auth использует схему Roles Based Access Control, которая базируется на ролях. Обычно с ролью выдаётся полный доступ к определённому сервису, вместо привязки к конкретному функционалу. Например, в пиццериях есть заместители управляющего, которые могут вести определенные проекты: составлять графики или учитывать сырьё. Но у нас нет выдачи прав на конкретные компоненты системы. Приходится выдавать полный доступ к сервису, чтобы сотрудники могли получить доступ к составлению графиков или настройкам какого-либо компонента учёта.
Проблемы подтолкнули к тому, чтобы спроектировать и написать новую версию Auth. На старте проекта мы потратили 3 недели только на изучение стандартов авторизации и аутентификации OAuth 2.0 и OpenID Connect 1.0.
Примечание. Утрированно, статья — это пересказ RFC, который приходилось перечитывать несколько раз, чтобы понять, что происходит вокруг. Здесь я постарался уйти от этой сложности и рассказать всё максимально просто, структурировано, кратко и без описания сложных вещей, например, какие символы может содержать в себе ответ сервиса. В отличии от RFC, прочитав это один раз, можно во всём разобраться. Надеюсь, статья будет полезна и сэкономит время при выборе решения для реализации сервиса аутентификации, а может, кого-то заставит задуматься о его необходимости.
Что такое ОAuth2.0?
Разработку нового Auth мы решили начать с изучения доступных протоколов и технологий. Самый распространённый стандарт авторизации — фреймворк авторизации OAuth2.0.
Стандарт был принят в 2012 году, и за 8 лет протокол меняли и дополняли. RFC стало настолько много, что авторы оригинального протокола решили написать OAuth 2.1, который объединит все текущие изменения по OAuth 2.0 в одном документе. Пока он на стадии черновика.
Актуальная версия OAuth описанна в RFC 6749. Именно его мы и разберем.
OAuth 2.0 — это фреймворк авторизации.
Он описывает, как должно реализовываться взаимодействие между сервисами для обеспечения безопасной авторизации. Многие нюансы описаны достаточно подробно, например, flow взаимодействия узлов между собой, но некоторые отдаются на откуп конкретной реализации.
В OAuth 2.0 определены четыре роли:
Важно: клиент должен быть заранее зарегистрирован в сервисе. Как это сделать?
Регистрация клиента
Способ регистрации клиента, например, ручной или service discovery, вы выбираете сами, в зависимости от фантазии конкретной реализации. Но при любом способе при регистрации, кроме ID клиента, должны быть обязательно указаны 2 параметра: redirection URI и client type.
Redirection URI — адрес, на который отправится владелец ресурса после успешной авторизации. Кроме авторизации, адрес используется для подтверждения, что сервис, который обратился за авторизацией, тот, за кого себя выдаёт.
Client type — тип клиента, от которого зависит способ взаимодействия с ним. Тип клиента определяется его возможностью безопасно хранить свои учётные данные для авторизации — токен. Поэтому существует всего 2 типа клиентов:
Токены
Токен в OAuth 2.0 — это строка, непрозрачная для клиента. Обычно строка выглядит как случайно сгенерированная — её формат не имеет значения для клиента. Токен — это ключ доступа к чему-либо, например, к защищённому ресурсу (access token) или к новому токену (refresh Token).
У каждого токена своё время жизни. Но у refresh token оно должно быть больше, т.к. он используется для получения access token. Например, если срок жизни access token около часа, то refresh token можно оставить жить на целую неделю.
Refresh token опционален и доступен только для confedential клиентов. Пользуясь опциональностью токена, в некоторых реализациях время жизни access token сделано очень большим, а refresh token вообще не используется, чтобы не заморачиваться с обновлением. Но это не безопасно. Если access token был скомпрометирован, его можно обнулить, а сервис получит новый Access token с помощью refresh token. В случае, если refresh token нет, то потребуется проходить процесс авторизации заново.
За access token закреплён определённый набор прав доступа, который выдаётся клиенту во время авторизации. Давайте разберёмся, как выглядят права доступа в OAuth 2.0.
Права доступа
Права доступа выдаются клиенту в виде scope. Scope – это параметр, который состоит из разделённых пробелами строк — scope-token.
На этапе регистрации клиента, в настройках сервиса авторизации клиенту выдаётся стандартный scope по умолчанию. Но клиент может запросить у сервера авторизации scope, отличный от стандартного. В зависимости от политик на сервере авторизации и выбора владельца ресурса, итоговый набор scope может выглядеть совсем иначе. В дальнейшем, после авторизации клиента, владелец ресурсов может отобрать часть прав без повторной авторизации сервиса, но, чтобы выдать дополнительные разрешения, потребуется повторная авторизация клиента.
Абстрактный OAuth 2.0. Flow c применением Access token
Мы рассмотрели роли, рассмотрели виды токенов, а также как выглядят scope. Посмотрим на flow предоставления доступа к сервису.
Ниже представлена абстрактная схема (или flow) взаимодействия между участниками. Все шаги на данной схеме выполняются строго сверху вниз. Разберём детальнее.
Абстрактный OAuth 2.0. Flow c применением Refresh token
Первый и второй шаги опущены из данной схемы — они ничем не отличаются от схемы абстрактного flow выше.
Что такое grant?
Grant — это данные, которые представляют из себя успешную авторизацию клиента владельцем ресурса, используемые клиентом для получения access token.
Например, когда мы где-либо аутентифицируемся с помощью Google, перед глазами всплывает уведомление. В нём говорится, что такой-то сервис хочет получить доступ к данным о вас или к вашим ресурсам (выводятся запрашиваемые scope-token). Это уведомление называется «Consent Screen».
В момент, когда нажимаем «ОК», в базу данных попадает тот самый grant: записываются данные о том, что такой-то пользователь дал такие-то доступы такому-то сервису. Клиент получает какой-то идентификатор успешной аутентификации, например строку, которая ассоциируется с данными в базе данных.
Существует 4 + 1 способа получения grant — grant type:
Client credentials grant flow
Имеет самый простой flow, напоминающий обычную авторизацию на любом сервисе. Она выполняется с помощью учётных данных клиента, которые представляют собой client id и client secret — аналог логина и пароля для пользователя. Так как для аутентификации требуется client secret, который должен соответствующе храниться, данный flow могут использовать только confedential клиенты.
Схема проста: клиент аутентифицируется на сервере авторизации передавая client id и client secret. В ответ получает access token, с которым уже может получить доступ к нужному сервису.
Этот flow требуется, когда клиент пытается получить доступ к своим ресурсам или ресурсам, заранее согласованным с сервером авторизации. Например, сервису А нужно время от времени ходить в сервис Б и актуализировать там данные о количестве пиццерий в сети.
Resource owner password credentials flow
По текущим рекомендациям безопасности описанных в данном RFC, данный flow не рекомендуется использовать вовсе из-за явных проблем с безопасностью.
Resource owner передаёт свой логин и пароль клиенту, например, через формы на клиенте. Клиент, в свою очередь, с помощью него получает access token (и, опционально, refresh token).
Здесь есть проблема. Resource owner просто берёт и отдаёт в открытом виде свой логин и пароль клиенту, что не безопасно. Изначально он был сделан только для клиентов, которым вы доверяете или тех, что являются частью операционной системы. Позже он был разрешён только для миграции с аутентификации по логину и паролю на OAuth 2.0. Текущие рекомендации по безопасности запрещают его использование.
Authorization code
Самый распространённый flow на данный момент. В основном используется для confidential клиентов, но с появлением дополнительной проверки с помощью PKCE, может применяться и для public-клиентов.
В данном flow взаимодействие client с resource owner проходит через user-agent (браузер). К user-agent есть одно требование: он должен уметь работать с HTTP-редиректами. Без этого resource owner не сможет попасть к серверу авторизации и вернуться обратно с grant.
Данный flow сложнее, чем предыдущие, поэтому будем разбирать по шагам. Для начала представим, что мы — resource owner и перешли на страницу сервиса онлайн-обучения, который хочет сохранять результаты обучения к нам в облако. Ему требуется получить доступ к нашему ресурсу, например, определённой директории в облаке. Мы нажимаем на «Авторизоваться» и начинается путешествие по Authorization code grant flow:
Следующий flow построен на основе этого.
Implicit grant
Это оптимизация Authorization code grant flow для public-клиентов, которые умеют работать с redirection URI. Например, для браузерных приложений на JavaScript, или мобильных приложений. Требование к user-agent, с помощью которого взаимодействуют клиент и resource owner, сохраняется: он должен уметь работать с HTTP-редиректами.
Между authorization code и implicit есть основное отличие: вместо получения authorization code и access token по нему, мы сразу получаем access token после успешной авторизации resource owner. Кроме того, здесь не используется client secret из соображений безопасности — приложение можно дизассемблировать и получить его. Подлинность проверяется только по redirection URI.
Многие шаги из данной схемы похожи на шаги из authorization code, но предлагаю их разобрать также подробно. Представим, что некое браузерное приложение хочет сохранять свои настройки в нашем Git-репозитории. Мы нажимаете «Войти в GitHub» и на этом этапе начинается работа Implicit flow:
Device authorization (RFC 8628)
С 2012 до 2019 появилось много умных устройств, на которых неудобно авторизоваться. Например, неудобно вводить сложный логин и пароль на телевизоре каждый раз при открытии ресурса. На некоторых устройствах это невозможно, например на серверных ОС без графического интерфейса. В августе 2019 этот flow появился как раз для таких сценариев.
Есть, как минимум, 3 требования к устройствам, чтобы работа с помощью Device authoraztion grant flow была возможна:
Возможно, схема кажется сложной из-за обилия стрелок. Разберём её также пошагово, как и разбирали сложные flow до него.
Представим, что мы пытаемся авторизоваться на web-сервисе с помощью телевизора. Мы видим кнопку «Авторизоваться как устройство» и нажимаем. В этот момент начинается наш Device flow:
Вместо вывода
В этой статье я опустил много подробностей, чтобы максимально просто и доступно рассказать о самом важном. Например, типы запросов, как и в каком виде передавать параметры, какие символы допустимы в качестве значений для того.
Если хотите погрузиться в тематику детальнее, то рекомендую в RFC 6749 (для OAuth 2.0) и RFC 8628 (для Device Flow). Кроме того, следить за актуальными версиями RFC можно на ресурсе, посвящённому OAuth.
Если статья была полезна и захотите подробностей — пишите в комментариях, и в следующих статьях расскажу о PKCE, о протоколе аутентификации OpenID Connect 1.0, о нашей реализации сервера аутентификации и многом другом.
Как работает OAuth 2.0 и OpenID Connect
Разбираемся, как работает протокол OAuth 2.0 и OpenID Connect. Почему Authorization Code Grand лучший способ получения access token.
Если коротко OAuth 2.0 — протокол авторизации, позволяющий выдать одному сервису (приложению) права на доступ к ресурсам пользователя на другом сервисе. Протокол избавляет от необходимости доверять приложению логин и пароль, а также позволяет выдавать ограниченный набор прав, а не все сразу.
В этой статье рассмотрим историю возникновения и схему работы. Разберемся в чем отличие OAuth 2.0 от OpenID Connect и что такое SSO.
История возникновения OAuth
Авторизацией через социальные сети никого уже не удивишь. Нажимаешь кнопку соц сети, вжух и ты авторизовался на новом сайте. Сайт получил твоё ФИО, фотку и прочие данные. Но так было не всегда.
В «каменном веке» интернета все было проще. Вы просто давали свой логин и пароль от одного сервиса другому, чтобы тот вошел в вашу учетную запись и получил любую необходимую ему информацию.
На заре становления Facebook просил у пользователей логин и пароль от Gmail аккаунта, чтобы отправить контактам приглашение. Такой подход имеет большую проблему: логин и пароль дают полный доступ к сервису. Поэтому был разработан стандарт OAuth.
С помощью этого стандарта вы позволяете приложению считать данные или использовать функции другого приложения от вашего имени, не сообщая ему свой пароль. Класс!
OAuth 1.0 не используется. Забудьте о нем. Используйте OAuth 2.0
Главным недостатком OAuth 1.0 была слишком большая сложность данной версии.
Начнем разбор OAuth 2.0 с ролей. Всего есть 4 роли:
Далее мы рассмотрим каждую из ролей.
Владелец ресурса
Ресурсом являются данные, например ФИО, фотография, ваши сообщения в соц сетях, и прочее. Владелец ресурса это пользователь. При межсерверном общении владельцем ресурса может быть один из серверов.
Сервер ресурсов
На сервере ресурсов лежат ваши данные. В случае с примером выше ваши контакты Gmail это ресурс, а лежат они на серверах Gmail.
Клиент
Клиент это сервис, которому требуется доступ к вашим ресурсам. Например, Facebook требуется доступ к контактам Gmail.
Авторизационный сервер
В данном примере он принадлежит Google, так как он хранит ваши данные.
Стандарт не запрещает вам объединить Сервер ресурсов и Авторизационный сервер
Базовая схема протокола
OAuth 2.0 основан на использовании базовых веб-технологий: HTTP-запросах, редиректах и т. п. Поэтому использование OAuth возможно на любой платформе с доступом к интернету и браузеру: на сайтах, в мобильных и desktop-приложениях, плагинах для браузеров.
Вернемся к нашему примеру про Facebook и Gmail. На анимации ниже, я постарался схематично изобразить, как реализовать этот пример правильно с помощью Oauth2. Стоит учитывать, что у Google есть свой сервер авторизации, который отвечает за авторизацию на любом сервисе Google. Поэтому Gmail только хранит ресурсы, но не отвечает за авторизацию.
Это строка, которая является альтернативой логину и паролю.
Особенности Access Token:
Помимо access_token Авторизационный сервер может выдавать также refresh_token. Это токен, который позволяет запросить новый access_token без участия Владельца ресурсов. Время жизни у такого токена намного больше access_token и его потеря гораздо серьезнее.
Вернемся к базовой схеме. Авторизационный сервер должен знать про каждого клиента, который делает к нему запрос. То есть, каждый клиент должен быть зарегистрирован. Зарегистрировав клиента мы получаем client_id и client_secret и обязаны передавать, как минимум client_id в каждом запросе.
Существует возможность регистрировать клиентов динамически: RFC 7591 и RFC 7592.
Способы получения Access Token
Всего есть 4 способа:
Client Credentials
Начнем разбор с самой простой схемы. Этот способ придуман для межсерверного взаимодействия. У нас есть два сервера API1 и API2, и им надо как-то общаться.
3. API 1 обращается к API 2.
4. API 2 получает запрос с access_token и обращается к авторизационному серверу для проверки действительности переданного токена (RFC 7662).
Resource Owner Password Credential
Эта схема не рекомендуется к использованию! В стандарте так и написано, если вы никакие другие схемы не можете сделать, то используйте эту.
Authorization Code Grand
Является одним из наиболее распространённых типов разрешения, поскольку он хорошо подходит для серверных приложений, где исходный код приложения и секрет клиента не доступны посторонним.
Этот способ рекомендуемый. Используйте его, и только если это невозможно, посмотрите на другие способы. Исключением является межсерверное общение.
Пример авторизационного запроса
В настройках Авторизационного сервера можно настроить url адреса, на которые разрешен редирект.
Так как code попадает в браузер и ничем не защищен, то это точка уязвимости. Поэтому на авторизационный код накладываются следующие ограничения:
5. Теперь, когда у вас есть код авторизации, вы должны обменять его на токены. Используя извлеченный код авторизации из предыдущего шага, вам нужно будет выполнить POST на URL-адрес токена.
7. Чтобы вызвать ваш API из обычного веб-приложения, приложение должно передать полученный токен доступа в заголовке авторизации вашего HTTP-запроса.
Implicit Grant
Так как access_token попадает в браузер, то существует возможность его достать.
OpenID Connect
OAuth 2.0 разработан только для авторизации — для предоставления доступа к данным и функциям от одного приложения другому. OpenID Connect (OIDC) — это тонкий слой поверх OAuth 2.0, добавляющий сведения о логине и профиле пользователя, который вошел в учетную запись.
OpenID Connect позволяет реализовывать сценарии, когда единственный логин можно использовать во множестве приложений, — этот подход также известен как single sign-on (SSO)
Заключение
Подведем итог. OAuth 2.0 это простой протокол авторизации, основанный на HTTP, что дает возможность применять его практически на любой платформе. Он имеет хорошую документацию, и большинство крупных площадок его поддерживают. Так что если вы решили использовать этот протокол в своем проекте — это хороший выбор.
Доступ к данным oauth выдача новых oauth токенов что это
Сегодня мы подробно разберем процесс получения OAuth-токена для доступа к Яндекс.Директ API. Впервые сталкиваясь с процессом получения токена, будь-то API от Google или Яндекса, я по-началу терялся в заявках, регистрациях и прочей бюрократической вакханалии. Поэтому я, буквально, за руку проведу тебя к заветному апи-токену, который мы сразу и проверим.
Как следует из справки Яндекс.Директ API, вся процедура делится на два этапа:
Регистрируем приложение в Яндекс.Директ API
Авторизуемся из под аккаунта с кабинетом Яндекс.Директ, данные которого нас интересуют. Переходим на страницу oauth.yandex.ru, и жмем на желтую кнопку «Зарегистрировать новое приложение». И заполняем поля, согласно плану:
Отлично, приложение создано, на выходе получится что-то похожее на это:
Отлично, пол дела сделано, осталось запросить доступ к API.
Создаем заявку на доступ к Яндекс.Директ API
Теперь создадим заявку, тут всё довольно просто. Идём сюда и создаем заявку на доступ. Начинаем заполнять:
Бум! Всё готово, отправляем на рассмотрение. После прохождения, в итоге получим такую картину:
Получаем OAuth-токен Яндекс.Директ:
Существует 2 способа получения API-токена: Ручной и Автоматический
Так как мы не пишем приложение, которое будут использовать десятки авторизованных пользователей, то нам хватит и ручного получения токена. Теперь дело за малым, делаем запрос на выдачу «API-ключа», который мы будем использовать в нашем приложении. Для этого:
Ну что, всё готово для тестового запроса, поехали?
Тестовый запрос для проверки работы Яндекс.Директ API:
Давайте запросим список текущих рекламных кампаний в кабинете?
Полезные материалы для изучения:
Автоматизация Яндекс.Директ. Часть 1
Совместно с коллегами из ADF Media — Артемом Дурневым и Султаном Назаралиевым, мы решили выпустить цикл из 6 статей, посвященных автоматизации процессов в Яндекс Директе. Сегодня вас ждет вступительная часть, в которой мы поговорим про API, токены Директа и Песочницу.
Чтобы автоматизировать работу Я.Директа, мы должны понимать, что такое API.
API — это составляющая часть сервиса, которая позволяет отправлять запросы и получать ответы.
Единого сценария работы с API нет. У каждого сервиса — сценарий свой. Единственное общее — это токены. Не важно с какой рекламной площадкой вы работаете, в любом случае вам нужно будет получать токен.
Токен — это «ключ» к сервису. Где-то токены нужно получать каждый час, а где-то вы должны владеть двумя «токенами» и передавать их на сервер, чтобы получать «истинный» токен в зашифрованном виде. А где-то вы просто получаете от системы один токен и пользуетесь им продолжительное время.
Так как мы говорим про Яндекс, то в нем получение токена организовано по принципу OAuth. Срок действия токена — один год.
OAuth — это протокол авторизации. Например, получив токен, вы можете передать его любому человеку для авторизации в сервисе, которым пользуетесь. Ему не нужно будет знать ваш логин и пароль, если у него есть токен.
Та же история с Я.Директом. Если вы передадите токен, человек сможет управлять рекламными кампаниями и скачивать данные из статистики за вас.
Токен Яндекс.Директа выглядит следующим образом:
Казалось бы, что это просто набор цифр и букв, но на самом деле каждый такой токен содержит следующую информацию:
Таким образом, токен показывает, что может делать данное приложение от имени определенного аккаунта.
Есть два варианта получения токена. Простой и сложный. Сложный заключается в том, что нам необходимо стать разработчиком и зарегистрировать приложение. Делается это следующим образом:
Указываем название приложения. В описании можно указать для чего создается приложение.
В графе «платформы” указываем веб-сервисы и нажимаем “Подставить URL для разработки».
Далее необходимо указать какие доступы мы можем запрашивать токеном.
После пройденных шагов, вы получите ID и пароль приложения.
После регистрации OAuth приложения нужно подать заявку на доступ к API Яндекс.Директ. Для этого заходим в Яндекс.Директ и переходим во вкладку API, как показано ниже.
Далее открываем «Мои заявки»
Смело нажимаем на «Полный доступ» и заполняем поля. Вот как заполнили мы:
В демо-доступе указали ссылку на Google Таблицу.
Срок рассмотрения заявки до 7 дней, но, как правило, рассмотрение занимает один-два дня. После этого заявка будет одобрена или отклонена. Как только приложение будет одобрено, вы сможете «вытаскивать» токены.
Переходим по ссылке вида:
(Не забудьте, поменять хвостик, заменив его на свой ID, который получили выше)
И в ответ на наш запрос — получаем токен.
Простой способ получения токена — Переходим на сайт ADF-media и авторизовываемся. В ответ на авторизацию, сайт покажет вам ваш токен.
Давайте сделаем первую часть цикла статей максимально полезной и поговорим еще и про Песочницу. Пока поверхностно, чтобы иметь о ней минимально представление.
Песочница — это среда для отладки приложений, взаимодействующих с API Директа.
Песочница имитирует API Директа, но полностью изолирована от настоящих данных. Это «игровая площадка», на которой можно вызывать методы API, получать ответы, наблюдать изменение тестовых кампаний и объявлений. Действия, которые доступны в API только при положительном балансе, в Песочнице доступны без фактического внесения средств.
Запросы к Песочнице не изменяют данные в Директе. Созданные объявления нигде не показываются, а списываемые и зачисляемые средства не влияют на настоящие кампании. Однако для кампаний имитируется полный набор состояний — от модерации до остановки показов при исчерпании средств. Статистические отчеты хотя и содержат условные данные, но по структуре совпадают с настоящими отчетами. Это делает Песочницу полнофункциональной средой для отладки приложений.
Песочница не имеет веб-интерфейса, и посмотреть тестовые кампании в интерфейсе невозможно. Работать с Песочницей можно только через вызовы методов API.
Но нужно помнить, что:
Мы знаем, что такое API, как зарегистрировать приложение и зачем это нужно, а также понимаем, что такое Песочница.
в следующей статье, мы воспользуемся полученными знаниями для передачи первых данных из Яндекс.Директа в Google Таблицы (без знания программирования).