如何POST以交换令牌的23andme身份验证代码

时间:2014-03-19 19:09:32

标签: ruby https uri 23andme-api

23andme网站有一个API,他们提供以下说明:

  

使用这些参数发送POST /令牌/请求(client_id和client_secret在您的信息中心上):

curl https://api.23andme.com/token/
 -d client_id=xxx \
 -d client_secret=yyy \
 -d grant_type=authorization_code \
 -d code=zzz \
 -d "redirect_uri=https://localhost:5000/receive_code/"
 -d "scope=basic%20rs3094315"
  

如果成功,您将获得200 JSON响应:

{"access_token":"89822b93d2",
 "token_type":"bearer",
 "expires_in": 86400,
 "refresh_token":"33c53cd7bb",
 "scope":"rs3094315 basic"}

所以,这是我尝试过的,但它没有用。我认识Ruby,但从未使用过net / http或uri。

def self.get_token(code)
    uri = URI.parse("https://api.23andme.com/token")
    https = Net::HTTP.new(uri.host, uri.port)
    https.use_ssl = true

    request = Net::HTTP::Post.new(uri.path)

    request["client_id"]     = 'my client id goes here'
    request["client_secret"] = 'my client secret goes here'
    request["grant_type"]    = 'authorization_code'
    request["code"]          = code
    request["redirect_uri"]  = 'http://localhost:3000'
    request["scope"]         = 'names basic haplogroups relatives'

    response = https.request(request)
    return response.to_s
end

2 个答案:

答案 0 :(得分:0)

您正在使用curl-d选项在POST请求正文中设置参数。但是,对于Net::HTTP::Post对象,语法request["key"] = value用于设置Http对象的标题

使用set_form_data将所有参数设置为POST请求的正文

例如,以这种方式使用它:

request.set_form_data({"client_id" => "my client id goes here", "code" => code})

以下将澄清以上内容:

$ > request["client_id"] = 'my client id goes here'
# => "my client id goes here" 
$ > request.body
# => nil # body is nil!!!
$ > request.each_header { |e| p e }
# "client_id"
# => {"client_id"=>["my client id goes here"]} 

$ > request.set_form_data("client_secret" => 'my client secret goes here')
# => "application/x-www-form-urlencoded" 
$ > request.body
# => "client_secret=my+client+secret+goes+here" # body contains the added param!!!

答案 1 :(得分:0)

我只想发布有效的代码。感谢Rafa。

def self.get_token(code)
    uri = URI.parse("https://api.23andme.com/token")
    https = Net::HTTP.new(uri.host, uri.port)
    https.use_ssl = true
    https.verify_mode = OpenSSL::SSL::VERIFY_NONE

    request = Net::HTTP::Post.new(uri.path,
                initheader = {'Content-Type' =>'application/json'})

    request.set_form_data({"client_id"     => 'my client id',
                           "client_secret" => 'my client secret',
                           "grant_type"    => 'authorization_code',
                           "code"          => code,
                           "redirect_uri"  => 'http://localhost:3000/receive_code/',
                           "scope"         => 'names basic haplogroups relatives'})

    response = https.request(request)
    data = JSON.load response.read_body

    return data["access_token"]
end