簡體   English   中英

從iNaturalist獲得API授權

[英]Getting authorization from iNaturalist for API

我正在嘗試通過Ruby on Rails使用iNaturalist的API。 我是Ruby的新手,而iNaturalist的文檔很少。 第一步,我需要弄清楚如何從他們的網站獲得授權。

iNaturalist提供以下示例代碼。 我使用iNaturalist設置了一個項目,並嘗試使用自己的憑據在Rails Console中運行示例代碼。 將以下行中的#{url}替換為用戶應該登錄到iNat所要使用的URL:放置“轉到#{url},批准該應用,您應該重定向到您的“ +“ redirect_uri。在此處復制並粘貼“代碼”參數。”

我轉到生成的網址並登錄: https : //www.inaturalist.org/oauth/authorize? client_id= [我的客戶ID]&redirect_uri = https://ruby_on_rails--timrobinson41199691.codeanyapp.com/login/&response_type=碼

iNaturalist回復“包含的重定向uri無效”。

如果我忽略&response_type = code,它將以“授權服務器不支持此響應類型”的形式響應。

我的網站在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后,應使用數據中提供的授權代碼將其重定向回到我的網站。 在routes.rb中,我的登錄路由設置為:

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

我也嘗試過使用get。

iNat返回上面提到的錯誤,並且未重定向回我的網站。

首先,OAuth可能有些令人生畏。 該指南實際上僅顯示了使用cURL測試您的API的等效功能。

在實際的應用程序中,當提供程序從授權重定向回時, redirect_uri是應用程序中處理響應的任何端點。

因此,讓我們設置一個最小的真實Rails應用程序。

1.注冊您的應用

注冊一個新的應用程序或編輯您現有的應用程序。 使用http://localhost:3000/oauth/inaturalist/callback作為回調URL(根據需要調整主機)。

將窗口保持打開狀態,因為稍后您將需要client_id和secret。

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

您實際上可以在沒有重定向路由的情況下執行此操作,而只需在視圖中添加指向https://www.inaturalist.org/oauth/authorize... url的鏈接。 但是擁有它可以將您的應用程序與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變量。

4.安裝oauth2 gem

# 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.inaturalist.org的api令牌。 但是細節有點稀疏。

5添加鏈接以登錄:

<%= link_to 'Sign in to iNaturalist.org', oauth_inaturalist_authorize_path %>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM