Как мне выполнить эту процедуру 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 Несанкционированную ошибку, и если я делаю, я обновляю свои токены.

Другие вопросы по тегам