简体   繁体   English

从iNaturalist获得API授权

[英]Getting authorization from iNaturalist for API

I'm trying to use iNaturalist's API via Ruby on Rails. 我正在尝试通过Ruby on Rails使用iNaturalist的API。 I'm new to Ruby and iNaturalist's documentation is pretty sparse. 我是Ruby的新手,而iNaturalist的文档很少。 As a first step, I need to figure out how to get authorization from their site. 第一步,我需要弄清楚如何从他们的网站获得授权。

iNaturalist provides the sample code below. iNaturalist提供以下示例代码。 I set up a project with iNaturalist and tried running the sample code in Rails Console with my credentials. 我使用iNaturalist设置了一个项目,并尝试使用自己的凭据在Rails Console中运行示例代码。 #{url} in the following line is replaced with a url that the user is supposed to go to in order to log in to iNat: puts "Go to #{url}, approve the app, and you should be redirected to your " + "redirect_uri. Copy and paste the 'code' param here." 将以下行中的#{url}替换为用户应该登录到iNat所要使用的URL:放置“转到#{url},批准该应用,您应该重定向到您的“ +“ redirect_uri。在此处复制并粘贴“代码”参数。”

I went to the resulting url and logged in: https://www.inaturalist.org/oauth/authorize?client_id=[my client id]&redirect_uri= https://ruby_on_rails--timrobinson41199691.codeanyapp.com/login/&response_type=code 我转到生成的网址并登录: https : //www.inaturalist.org/oauth/authorize? client_id= [我的客户ID]&redirect_uri = https://ruby_on_rails--timrobinson41199691.codeanyapp.com/login/&response_type=码

iNaturalist responds with "The redirect uri included is not valid." iNaturalist回复“包含的重定向uri无效”。

If I leave off &response_type=code, it responds with "The authorization server does not support this response type." 如果我忽略&response_type = code,它将以“授权服务器不支持此响应类型”的形式响应。

My website is on codeanywhere.com. 我的网站在codeanywhere.com上。 The url of the main page is " https://ruby_on_rails--timrobinson41199691.codeanyapp.com/ ". 主页的URL是“ https://ruby_on_rails--timrobinson41199691.codeanyapp.com/ ”。 Part of the problem is that I don't understand what kind of page I'm supposed to create for redirect_uri, since I'm still kind of new at this. 问题的部分原因是我不了解应该为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

After the user logs in to iNat, he should be redirected back to my website with the authorization code provided in the data. 用户登录到iNat后,应使用数据中提供的授权代码将其重定向回到我的网站。 In routes.rb, my login route is set as: 在routes.rb中,我的登录路由设置为:

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

I've tried using get, as well. 我也尝试过使用get。

iNat is returned the error mentioned above and not redirecting back to my site. iNat返回上面提到的错误,并且未重定向回我的网站。

OAuth can be a bit daunting at first. 首先,OAuth可能有些令人生畏。 And that guide really just shows the equivalent of using cURL to test your API. 该指南实际上仅显示了使用cURL测试您的API的等效功能。

In an actual application redirect_uri is whatever endpoint in your application that handles the response when the provider redirects back from authorization. 在实际的应用程序中,当提供程序从授权重定向回时, redirect_uri是应用程序中处理响应的任何端点。

So lets setup a minimal real rails app. 因此,让我们设置一个最小的真实Rails应用程序。

1. Register your app 1.注册您的应用

Register a new application or edit your existing app. 注册一个新的应用程序或编辑您现有的应用程序。 Use http://localhost:3000/oauth/inaturalist/callback for the callback url (adjust the host as needed). 使用http://localhost:3000/oauth/inaturalist/callback作为回调URL(根据需要调整主机)。

Keep the window open as you will need the client_id and secret in a moment. 将窗口保持打开状态,因为稍后您将需要client_id和secret。

2. Setup your routes 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

You can actually do this without the redirect route and just plant a link to the https://www.inaturalist.org/oauth/authorize... url in your view. 您实际上可以在没有重定向路由的情况下执行此操作,而只需在视图中添加指向https://www.inaturalist.org/oauth/authorize... url的链接。 But having it isolates your application against the craziness that is OAuth and its how OmniAuth does it. 但是拥有它可以将您的应用程序与OAuth的疯狂以及OmniAuth的工作方式隔离开来。

3. Add your credentials to the Rails app. 3.将您的凭据添加到Rails应用程序。

In Rails 5 use the encrypted credentials to store your client_id and secret. 在Rails 5中,使用加密的凭据存储您的client_id和密码。

Run $ bin/rails credentials:edit from your shell. 从您的外壳运行$ bin/rails credentials:edit

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

In earlier versions use ENV vars instead. 在早期版本中,请使用ENV变量。

4. Install the oauth2 gem 4.安装oauth2 gem

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

Then run bundle install . 然后运行bundle install

4. Setup the controller 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 here is actually a new OAuth2::AccessToken instance that can be called to call endpoints with the fetched credentials. token实际上是一个新的OAuth2::AccessToken实例,可以使用获取的凭据调用该实例以调用端点。

This example stores the token in the session. 本示例将令牌存储在会话中。 You can retrieve it in subsequent requests with: 您可以使用以下命令在后续请求中检索它:

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

The docs kind of mention trading the oauth access token for an api token for api.inaturalist.org . 文档中提到将oauth访问令牌替换api.inaturalist.org的api令牌。 But the details are kind of sparse. 但是细节有点稀疏。

5 Add a link to sign in: 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