2

我正在尝试通过https://launchpad.net使用 sinatra 和自定义omniauth 策略提取请求令牌

require 'omniauth-oauth'                                                                                                                
require 'oauth/signature/plaintext'                                                                                                     
require 'multi_json'                                                                                                                    
require 'pp'                                                                                                                            

module OmniAuth                                                                                                                         
  module Strategies                                                                                                                     
    class Launchpad < OmniAuth::Strategies::OAuth                                                                                       
      option :name, "launchpad"                                                                                                         
      option :client_options, {                                                                                                         
        :authorize_url => 'https://launchpad.net/+authorize-token',                                                                     
        :request_token_url => 'https://launchpad.net/+request-token',                                                                   
        :site => 'https://api.launchpad.net',                                                                                           
        :consumer_key => 'rubystfu',                                                                                                    
        :signature_method => 'PLAINTEXT',                                                                                               
        :signature => '%26'                                                                                                             
      }                                                                                                                                 

      def request_phase                                                                                                                 
        super                                                                                                                           
      end                                                                                                                               

      uid {                                                                                                                             
        raw_info[:name]                                                                                                                 
      }                                                                                                                                 

      info do                                                                                                                           
        {                                                                                                                               
          :description => raw_info['description'],                                                                                      
          :name => raw_info['name'],                                                                                                    
          :display_name => raw_info['display_name'],                                                                                    
          :karma => raw_info['karma'],                                                                                                  
          :self_link => raw_info['self_link'],                                                                                          
          :email => raw_info['email']                                                                                                   
        }                                                                                                                               
      end                                                                                                                               

      extra do                                                                                                                          
        {                                                                                                                               
          :raw_info => raw_info                                                                                                         
        }                                                                                                                               
      end                                                                                                                               

      def raw_info                                                                                                                      
        raw_info                                                                                                                        
      end                                                                                                                               
    end                                                                                                                                 
  end                                                                                                                                   
end  

我已经以这种方式设置了我的 sinatra 应用程序

#!/usr/bin/env ruby                                                                                                                     
require 'rubygems'                                                                                                                      
require 'bundler'                                                                                                                       

Bundler.setup :default, :development, :chonk                                                                                            

require 'sinatra'                                                                                                                       
require 'haml'                                                                                                                          
require 'omniauth-launchpad'                                                                                                            

use Rack::Session::Cookie                                                                                                               

use OmniAuth::Builder do                                                                                                                
  provider :launchpad                                                                                                                   
end                                                                                                                                     

set :sessions, true                                                                                                                     
set :logging, true                                                                                                                      

class ChonkApp < Sinatra::Application                                                                                                   
  helpers do                                                                                                                            
    def check_auth                                                                                                                      
      redirect "/" if not session[:user]                                                                                                
    end                                                                                                                                 
  end                                                                                                                                   

  get '/' do                                                                                                                            
    redirect "/app" if session[:user]                                                                                                   
    haml :index                                                                                                                         
  end                                                                                                                                   

  get '/app' do                                                                                                                         
    check_auth                                                                                                                          
    "#{session[:user]} | <a href='/logout'>logout</a>"                                                                                  
  end                                                                                                                                   

  get '/logout' do                                                                                                                      
    session.clear                                                                                                                       
    redirect '/'                                                                                                                        
  end                                                                                                                                   

  %w(get post).each do |method|                                                                                                         
    send(method, "/auth/:name/callback") do                                                                                             
      auth = request.env['omniauth.auth']                                                                                               
      a = auth.info                                                                                                                     
      session[:user] = "%s %s (%s)" % [a.email, a.name, a.nickname]                                                                     
      redirect "/app"                                                                                                                   
    end                                                                                                                                 
  end                                                                                                                                   

  get '/auth/failure' do                                                                                                                
    "I dunno wtfook happened."                                                                                                          
  end                                                                                                                                   
end 

文档说明它需要 3 个发布的参数才能工作:

要获取请求令牌,请向https://launchpad.net/+request-token发送 POST 请求 。(注意:不是 api.launchpad.net!)这与 Web 浏览器在提交表单时所做的 POST 相同。您应该以表单 URL 编码格式提交以下值。

oauth_consumer_key:您的消费者密钥 oauth_signature_method:字符串“PLAINTEXT” oauth_signature:字符串“&”。

因此 HTTP 请求可能如下所示:

POST /+request-token HTTP/1.1
Host: launchpad.net
Content-type: application/x-www-form-urlencoded

oauth_consumer_key=just+testing&oauth_signature_method=PLAINTEXT&oauth_signature=%26 The response should look something like this:


200 OK

oauth_token=9kDgVhXlcVn52HGgCWxq&oauth_token_secret=jMth55Zn3pbkPGNht450XHNcHVGTJm9Cqf5ww5HlfxfhEEPKFflMqCXHNVWnj2sWgdPjqDJNRDFlt92f

我能看到的唯一可能不正确的是 signature_method 和/或签名。我对红宝石很陌生,所以任何建议都值得赞赏。返回的错误是“未经授权的 401”,我还没有完全弄清楚如何在请求期间打印一些关于传递给https://launchpad.net的调试输出。

用于签署请求的文档的链接在这里: https ://help.launchpad.net/API/SigningRequests

谢谢

ps omniauth-launchpad 的来源是https://github.com/battlemidget/omniauth-launchpad,实际应用程序的来源是https://github.com/battlemidget/chonk

4

0 回答 0