Как мне выполнить эту процедуру OAuth без сервера?
Я использую гем ruby-box для подключения к box.com, где говорится, что использовать этот код для получения токена доступа:
session = RubyBox::Session.new({
client_id: $boxClientID,
client_secret: $boxClientSecret
})
authorize_url = session.authorize_url('https://redirect-url-in-app-settings')
@token = session.get_access_token('code-returned-to-redirect_url')
Проблема в том, что у меня нет URL для перенаправления, и я также не использую графический интерфейс, поэтому я не могу получить код оттуда. Что я делаю?
3 ответа
Бен, я один из разработчиков Gem в рубиновом боксе. Вот что вы можете сделать:
- на app.box.com настройте приложение для использования этого обратного вызова
https://localhost/oauth2callback
- в IRB создайте URL авторизации, используя тот же обратный вызов:
session = RubyBox:: Session.new ({ client_id: $ boxClientID, client_secret: $ boxClientSecret }) authorize_url = session.authorize_url ('https: // localhost / oauth2callback')
- вставьте этот URL в веб-браузер.
- как только вы аутентифицируетесь с помощью Box, вы окажетесь на странице обратного вызова с URL-адресом, который выглядит следующим образом:
https://localhost/oauth2callback?state=&code=OQpfImZH35Ab9weUy61kthIvqZ2Dyz6
- Скопируйте значение кода.
- Вернувшись в irb, запустите эту команду:
token = session.get_access_token('OQpfImZH35Ab9weUy61kthIvqZ2Dyz6')
access_token = token.token
refresh_token = token.refresh_token
- Храните токен доступа и токен обновления в базе данных (или на салфетке, или там, где вы считаете нужным).
- Отныне вы можете создавать такие сеансы:
session = RubyBox::Session.new({
access_token: $storedAccessTokenValue,
refresh_token: $storedRefreshTokenValue,
client_id: $boxClientID,
client_secret: $boxClientSecret
})
client = RubyBox::Client.new(session)
Вам нужно получить access_token и refresh_token только один раз для пользователя.
Поэтому одна проблема заключается в том, что срок действия маркеров доступа и обновления истекает - я не думаю, что вы можете хранить эти токены бесконечно и продолжать создавать экземпляры сеансов RubyBox навсегда. Если вы хотите что-то невероятно небезопасное (с точки зрения того, что сценарий будет хранить имя пользователя и пароль), но оно работает, вы можете использовать Mechanize, чтобы пройти интерактивную часть GUI. Вот сценарий, который я написал сегодня, чтобы решить ту же проблему. Обратите внимание, что вам НУЖНО иметь URI перенаправления для oauth2, и я не смог выяснить, как заставить Mechanize выжить, предоставив ему абсолютно недействительный URL. URI должен быть https, поэтому я выбрал https://www.chase.com/ случайно. Содержание этой страницы не имеет значения, важно то, что код аутентификации добавляется к URL перенаправления, и это то, что мне нужно.
Но опять же, это полностью противоречит цели oauth2, где вы предоставляете права на приложения, не раскрывая свой собственный пароль. Так что используйте с осторожностью...
Кроме того, он опирается на структуру формы и имена переменных в формах авторизации на box.com, которые могут измениться в любое время, что, я полагаю, сделает это немного хрупким.
require 'ruby-box'
require 'mechanize'
require 'cgi'
# get as new box session
box_session = RubyBox::Session.new({
client_id: 'your-client-id',
client_secret: 'your-client-secret'
})
# Get the authorization URL from Box by specifying redirect URL
# as the arbitrary but working Chase bank home page
authorize_url = box_session.authorize_url('https://www.chase.com')
agent = Mechanize::new
# process the first login screen
login_page = agent.get(authorize_url)
# get the login form where you enter the username and password
login_form = login_page.form_with(name: 'login_form1')
login_form.login = 'your-box-username'
login_form.password = 'your-box-password'
# submit the form and get the allow/deny page back
allow_page = agent.submit(login_form)
# find the form that allows consent
consent_form = allow_page.form_with(name: 'consent_form')
# now find the button that submits the allow page with consent
accept_button = consent_form.button_with(name: 'consent_accept')
# Submit the form to cause the redirection with authentication code
redirpage = agent.submit(consent_form, accept_button)
# Use the CGI module to get a hash of the variables (stuff after ?)
# and then the authentication code is embedded in [" and "] so
# strip those
code_query = CGI::parse(redirpage.uri.query)["code"].to_s
box_authentication_code = code_query[2,code_query.length-4]
# get the box access token using the authentication code
@token = box_session.get_access_token(box_authentication_code)
# print the tokens to show we have them
p @token.token
p @token.refresh_token
# Create a new Box client based on the authenticated session
client = RubyBox::Client.new(box_session)
# prove it works by getting list of folders in root directory
folders = client.root_folder.folders
p folders
Я использую python, а не ruby, поэтому я не могу рассказать вам, как это кодировать, но я могу поделиться с вами тем, как я решил обойти эту проблему.
Я пишу скрипт на python, который будет наблюдать за очередью событий на коробке, а затем обрабатывать новые файлы по мере их загрузки пользователями.
Поскольку скрипт на python автоматизирован, я собираюсь использовать генератор токенов, размещенный на heroku ( http://box-token-generator.herokuapp.com/), и использую его для запуска аутентификации моего приложения. Каждый раз, когда я делаю запрос, я проверяю, получаю ли я 401 Несанкционированную ошибку, и если я делаю, я обновляю свои токены.