Получение авторизации от iNaturalist для API - PullRequest
0 голосов
/ 12 апреля 2019

Я пытаюсь использовать API iNaturalist через Ruby on Rails.Я новичок в Ruby, и документация iNaturalist довольно скудная.В качестве первого шага мне нужно выяснить, как получить авторизацию на их сайте.

iNaturalist предоставляет приведенный ниже пример кода.Я настроил проект с iNaturalist и попытался запустить пример кода в консоли Rails с моими учетными данными.# {url} в следующей строке заменяется URL-адресом, на который пользователь должен перейти, чтобы войти в iNat: ставит «Перейти к # {url}, утвердите приложение, и вы должны быть перенаправлены на ваш»+ "redirect_uri. Скопируйте и вставьте сюда параметр 'code'."

Я пришел к полученному URL и вошел в систему: https://www.inaturalist.org/oauth/authorize?client_id=[my идентификатор клиента] & redirect_uri = https://ruby_on_rails -timrobinson41199691.codeanyapp.com/login/&response_type=code

iNaturalist отвечает: «Включенный URI перенаправления недействителен».

Если я оставляю код & response_type =, он отвечает с помощью«Сервер авторизации не поддерживает этот тип ответа.»

Мой сайт находится на codeanywhere.com.URL главной страницы: «https://ruby_on_rails - timrobinson41199691.codeanyapp.com/».Отчасти проблема в том, что я не понимаю, какую страницу я должен создать для redirect_uri, поскольку я все еще новичок в этом.

require 'rubygems'
require 'rest_client'
require 'json'

site = "https://www.inaturalist.org"
app_id = 'YOUR APP ID'
app_secret = 'YOUR APP SECRET'
redirect_uri = 'YOUR APP REDIRECT URI' # you can set this to some URL you control for testing

# REQUEST AN AUTHORIZATION CODE
# Your web app should redirect the user to this url. They should see a screen
# offering them the choice to authorize your app. If they aggree, they will be
# redirected to your redirect_uri with a "code" parameter
url = "#{site}/oauth/authorize?client_id=#{app_id}&redirect_uri=#{redirect_uri}&response_type=code"

# REQUEST AN AUTH TOKEN
# Once your app has that code parameter, you can exchange it for an access token:
puts "Go to #{url}, approve the app, and you should be redirected to your " + 
  "redirect_uri. Copy and paste the 'code' param here."
print "Code: "
auth_code = gets.strip
puts

payload = {
  :client_id => app_id,
  :client_secret => app_secret,
  :code => auth_code,
  :redirect_uri => redirect_uri,
  :grant_type => "authorization_code"
}
puts "POST #{site}/oauth/token, payload: #{payload.inspect}"
puts response = RestClient.post("#{site}/oauth/token", payload)
puts
# response will be a chunk of JSON looking like
# {
#   "access_token":"xxx",
#   "token_type":"bearer",
#   "expires_in":null,
#   "refresh_token":null,
#   "scope":"write"
# }

# Store the token (access_token) in your web app. You can now use it to make authorized
# requests on behalf of the user, like retrieving profile data:
token = JSON.parse(response)["access_token"]
headers = {"Authorization" => "Bearer #{token}"}
puts "GET /users/edit.json, headers: #{headers.inspect}"
puts RestClient.get("#{site}/users/edit.json", headers)
puts

После того, как пользователь войдет вiNat, он должен быть перенаправлен обратно на мой сайт с кодом авторизации, указанным в данных.В rout.rb мой маршрут входа в систему установлен так:

post '/login', to: 'organisms#login'

Я также пытался использовать get.

iNat возвращает ошибку, упомянутую выше, и не перенаправляет обратно на мойсайт.

1 Ответ

1 голос
/ 14 апреля 2019

OAuth поначалу может быть немного сложным.И это руководство действительно показывает эквивалент использования cURL для тестирования вашего API.

В реальном приложении redirect_uri - это любая конечная точка в вашем приложении, которая обрабатывает ответ, когда провайдер перенаправляет обратно из авторизации.

Итак, давайте настроим приложение минимального реального рельса.

1.Зарегистрируйте ваше приложение

Зарегистрируйте новое приложение или отредактируйте существующее приложение.Используйте http://localhost:3000/oauth/inaturalist/callback для URL обратного вызова (при необходимости измените хост).

Держите окно открытым, так как вам понадобится client_id и секрет в данный момент.

2.Настройте ваши маршруты

# /config/routes.rb
Rails.application.routes.draw do
  # just make sure you have a root path defined.
  root to: 'pages#home'
  namespace :oauth do
    namespace :inaturalist, controller: :callbacks do
      # This is just a simple redirect route
      get '/', action: :passthru, as: :authorize
      # This is the route that handles the actual callback
      get 'callback'
    end
  end
end

Вы можете сделать это без маршрута перенаправления и просто установить ссылку на URL https://www.inaturalist.org/oauth/authorize... в своем представлении.Но наличие этого изолирует ваше приложение от сумасшествия, которое есть OAuth и как OmniAuth делает это.

3.Добавьте свои учетные данные в приложение Rails.

В Rails 5 используйте зашифрованные учетные данные для хранения вашего client_id и секрета.

Запустите $ bin/rails credentials:edit из вашей оболочки.

inaturalist:
  client_id: <from the inaturalist site>
  secret: <from the inaturalist site>

В более ранних версиях вместо этого используйте ENV vars.

4.Установите камень oauth2

# Place this in your gemfile outside any groups
gem 'oauth2', '~> 1.4', '>= 1.4.1'

Затем запустите bundle install.

4.Настройте контроллер

# app/controllers/oauth/inaturalist/callbacks_controller.rb
require 'oauth2'

module Oauth
  module Inaturalist
    class CallbacksController < ::ActionController::Base

      # GET /oauth/inaturalist
      def passthru
        redirect_to client.auth_code.authorize_url
      end

      # This endpoint is where the provider redirects the user back to 
      # after authorization.
      # GET /oauth/inaturalist/callback
      def callback
        # Fetch an auth token from the access code
        token = client.auth_code.get_token(params[:code])
        # Perform an authenticated request to get the users data
        api_response = token.get("/users/edit.json")
        @user_data = JSON.parse(api_response.body)
        # This is just an example of how you can use the user data from
        # the provider
        @user = {
          uid: @user_data["id"],
          nickname: @user_data["nickname"]
        }
        session[:user_id] = @user[:uid]
        session[:token] = token.to_hash
        redirect_to root_path, success: "Hello #{@user[:nickname]}"
      end

      private
      # Change this if you are not using Rails 5 credentials.
      def client
        OAuth2::Client.new(
          credentials.fetch(:client_id),
          credentials.fetch(:secret),
          site: "https://www.inaturalist.org",
          redirect_uri: oauth_inaturalist_callback_url
        )
      end
      def credentials
        Rails.application.credentials.fetch(:inaturalist)
      end
    end
  end
end

token здесь на самом деле новый экземпляр OAuth2::AccessToken, который можно вызывать для вызова конечных точек с выбранными учетными данными.

В этом примере токен хранится в сеансе.Вы можете получить его в последующих запросах с помощью:

token = OAuth2::AccessToken.from_hash( session[:token] )

В документе упоминается о обмене токена доступа oauth на токен api для api.inaturalist.org .Но детали довольно редки.

5 Добавьте ссылку для входа в систему:

<%= link_to 'Sign in to iNaturalist.org', oauth_inaturalist_authorize_path %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...