GMA*_*GMA 10 ruby ruby-on-rails oauth omniauth aweber
我正在尝试使用官方的aweber gem将我的Rails应用程序与Aweber通过OAuth集成.
如果我在Rails控制台中关注他们的流程,我可以获得访问令牌,没有问题:
oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
puts oauth.request_token.authorize_url
# => https://auth.aweber.com/1.0/oauth/authorize?oauth_token=xxxxxxxxxxxxxx
Run Code Online (Sandbox Code Playgroud)
然后我访问该URL,输入我的凭据,获取验证码,然后返回rails控制台:
oauth.authorize_with_verifier 'xxxxxx'
# => #<OAuth::AccessToken>
Run Code Online (Sandbox Code Playgroud)
成功!
问题是,我想在现实世界中这样做,而不仅仅是在控制台上,这意味着我的Ruby代码需要分解为两个单独的操作.首先,控制器操作重定向到Aweber的Oauth页面:
def aweber
oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
redirect_to oauth.request_token(oauth_callback: "http://127.0.0.1:3000/auth/aweber/callback").authorize_url
end
Run Code Online (Sandbox Code Playgroud)
然后是用户输入其凭据并被重定向后获取访问令牌的操作:
def aweber_callback
oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
oauth.authorize_with_verifier(params[:oauth_verifier])
end
Run Code Online (Sandbox Code Playgroud)
当我这样做时,最后一行(authorize_with_verifier)总是提升#<OAuth::Unauthorized: 401 Unauthorized>.
似乎问题是我正在初始化oauth变量两次,这意味着我有两个不相关的实例AWeber::Oauth...而且只有生成authorize_url的AWeber :: Oauth实例才能获得访问令牌.但我无法在两者中获得相同的实例aweber_callback,aweber因为我正在处理两个完全不同的线程和控制器实例.
当我检查时oauth,我可以看到内部变量oauth.request_token.params["oauth_token"]并且oauth.request_token.params["oauth_token_secret"]每个变量都不同oauth,我猜这是导致问题的原因.我可以oauth_token从params(params[:oauth_token])获得'正确' ,但我无法弄清楚如何获得正确的oauth_token_secret(更不用说手动设置这样的实例变量感觉非常 hacky并且可能不是最好的方法.)
如何生成访问令牌?
我终于oauth_token_secret在会话中存储了这个工作.(而且我不得不说,我对Aweber的文档和API设置非常不满意.这比它应该的时间长10倍.)
的Gemfile
gem 'aweber', '~> 1.6.1', require: "aweber"
路线
get "auth/aweber", to: "integrations#aweber", as: :aweber
get "auth/aweber/callback", to: "integrations#aweber_callback", as: :aweber_callback
Run Code Online (Sandbox Code Playgroud)
集成控制器
def aweber
oauth = get_aweber_oauth
request_token = oauth.request_token(oauth_callback: aweber_redirect_uri)
session[:aweber_oauth_token_secret] = request_token.secret
redirect_to request_token.authorize_url
end
def aweber_callback
oauth = get_aweber_oauth
oauth.request_token = OAuth::RequestToken.from_hash(
oauth.consumer,
oauth_token: params[:oauth_token],
oauth_token_secret: session[:aweber_oauth_token_secret],
)
access_token = oauth.authorize_with_verifier(params[:oauth_verifier])
# TODO save access_token.token and access_token.secret
end
private
def get_aweber_oauth
AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
end
def aweber_redirect_uri
@_aweber_callback_uri ||= begin
if Rails.env.production?
redirect_host = "http://myproductionurl.com"
else
redirect_host = "http://127.0.0.1:3000"
end
"#{redirect_host}#{Rails.application.routes.url_helpers.aweber_callback_path}"
end
end
Run Code Online (Sandbox Code Playgroud)
下一步是存储access_token.token并.secret在我的数据库中,然后我将能够在未来的请求中授权用户,如下所示:
oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
oauth.authorize_with_access(current_user.aweber_token, current_user.aweber_secret)
aweber = AWeber::Base.new(oauth)
# Make calls using "aweber"...
Run Code Online (Sandbox Code Playgroud)
我尝试将gem omniauth-aweber与gem 结合使用omniauth,但我无法使它工作(这是一种耻辱,因为我omniauth-xxx在这个应用程序中使用其他宝石,保持一致性会很好.)基本上, gem会自动处理/auth/aweber流程的一部分,但在将它重定向回到/auth/aweber/callback/我之后,我看不到任何方式来获取oauth_token_secret- 它不在请求参数,会话或cookie中.
我现在已经回答了我自己的问题,但是我会给那些能够对上述内容做出明显改进的人,或者想办法让它全部合作omniauth-aweber.
通读 AWeber API Ruby 库,这一点很突出
\n\n\n如果我不想每次都验证怎么办?
\n验证一次后,oauth 对象包含\nauth.access_token.token 和 oauth.access_token.secret,\n它们可用于授权您的应用程序,而无需通过\nurl 进行验证:
\nRun Code Online (Sandbox Code Playgroud)\n... oauth.authorize_with_verifier('verification_code') puts 'Access\ntoken: ' + oauth.access_token.token puts 'Access token secret: ' +\noauth.access_token.secret The token and secret can then be saved, and\n授权可以按如下方式进行:
\nRun Code Online (Sandbox Code Playgroud)\nrequire 'aweber'\noauth = AWeber::OAuth.new('consumer_key', 'consumer_secret')\n#Rather than authorizing with the verification code, we use the token and secret \noauth.authorize_with_access(YOUR_ACCESS_TOKEN, YOUR_ACCESS_TOKEN_SECRET) \naweber = AWeber::Base.new(oauth)\n
让我们来看看:
\n您可以创建一个类,在内存中为每个用户保留一个对象足够的时间来完成登录,然后保存令牌和机密以供使用,直到它们过期。
\n请注意 current_user 是唯一标识用户的任何内容。如果您的用户此时尚未登录,您可以使用会话 ID
\nclass AWeberSignIn\n \n def self.start_signing user\n oauth = Rails.cache.fetch("#{user}/aweber", expires_in: 5.minutes) do\n AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])\n end\n oauth.request_token(oauth_callback: "http://127.0.0.1:3000/auth/aweber/callback").authorize_url\n end\n\n def self.authorize_with_verifier user, oauth_verifier\n oauth = Rails.cache.fetch("#{user}/aweber")\n oauth.authorize_with_verifier(oauth_verifier)\n [oauth.access_token.token, oauth.access_token.secret]\n end\n\n def self.get_base_from_token token, secret\n oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])\n oauth.authorize_with_access(token, secret)\n AWeber::Base.new(oauth)\n end\nend\nRun Code Online (Sandbox Code Playgroud)\n使用此类,您的控制器方法将变为:
\ndef aweber\n redirect_to AWeberSignIn.start_signin current_user #Assuming you have a current_user helper. Use whatever gives you a unique value per user\nend\n\ndef aweber_callback\n token, secret = AWeberSignIn.authorize_with_verifier(current_user, params[:oauth_verifier]) \n #Do something with token and secret. Maybe save it to User attributes?\n #You can then use them to get a AWeber base object via AWeberSignIn.get_base_from_token token, secret\nend\nRun Code Online (Sandbox Code Playgroud)\n请注意,这是使用低级 Rails 缓存。如果您想要与默认设置不同的内容,请确保设置缓存技术
\n| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |