使用Doorkeeper& amp;连接到Rails API时无法注销iOS Swift应用程序设计

时间:2015-11-17 20:53:39

标签: ios ruby-on-rails devise doorkeeper

好的 - 48小时后我放弃了。我有我的Rails 3.2 app设置与Doorkeeper和Devise。 doorkeeper.rb初始化程序非常简单:

resource_owner_authenticator do 
  current_account || warden.authenticate!(:scope => :account)
end

我在iOS Swift应用程序中使用了非常棒的p2_oauth POD进行OAuth2连接。这是问题/怪异:

当我开始登录并开始OAuth2舞蹈时,p2使用iOS的嵌入式Web视图来点击我的Rails API。由于没有current_account,它会适当地重定向到登录。大。

但是 - 我无法退出。

我已经尝试了一切:

  • warden.logout
  • signout
  • 使用Session.delete( “warden.user.account.key”)
  • 在调用注销路由时清除Rails应用程序中的cookie
  • 在调用注销路由时清除Rails应用程序中的会话

无论我做什么,当我再次登录时,Rails应用程序正在保留current_account!?我检查了会话,果然,会话中还有一个warden.user.account.key!这令人气愤。

如果我在模拟器中停止并重新启动iOS应用程序,则一切顺利,直到我登录/注销。很明显,就像iOS正在维护并且没有清除Rails应用程序正在阅读的会话。我还确保我的请求没有缓存策略:

    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.HTTPMethod = "DELETE"

    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    config.URLCache = nil
    let session = NSURLSession(configuration: config)

    let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: 

老实说,我不相信没有其他人遇到这个。我怎么想用这个设置注销?

3 个答案:

答案 0 :(得分:1)

只是想跟进你的评论。

回顾一下我带来的问题: 用户可以登录,但无法正常注销。一旦他们再次点击登录,它将自动登录而无需再次输入密码。

正如您所说,使用密码授予流程确实可以避免cookie会话。对我来说,我不得不在我的iOS应用程序中使用某种类型的webview。所以我必须坚持使用 authorization_code 授予。

我花了整整一个星期的时间试图弄清楚门卫 + 设计(我所有的链接都是紫色......)发生了什么,我终于找到了解决方案对我有用。我不确定这是否正确,因为我根本不熟悉铁轨上的红宝石。我以后必须再次查看代码。

基本上,该怎么办是将此添加到 config / routes.rb ,其中你说user_doorkeeper

use_doorkeeper do
    controllers applications: 'doorkeeper', authorizations: 'authorizations'
end

然后在此处添加授权控制器 app / controllers / authorizations_controller.rb

class AuthorizationsController < Doorkeeper::AuthorizationsController
  def new
    super
    env['warden'].logout
  end
end

这会强制用户注销登录。对于代码,我认为它正在做的是覆盖/添加代码到Doorkeeper中的原始AuthorizationsController。

我发现这个解决方案看起来像某人的博客,谢谢你,先生!这将暂时做到。 http://www.kluks.de/blog/posts/14-rails-4-single-sign-out-of-all-applications-with-doorkeeper

------------编辑------------

作为参考,对于提供者方,我一直在关注这个guide,同时添加我需要的东西。我不建议遵循她的客户端教程。这根本不适合我。

<强> doorkeeper.rb

Doorkeeper.configure do
use_refresh_token
force_ssl_in_redirect_uri false

#for authorization_code grant
resource_owner_authenticator do
    current_user || begin
        session[:user_return_to] = request.fullpath
        redirect_to new_user_session_url
    end
end

end

答案 1 :(得分:1)

我们遇到了类似的问题,后端设置相同,但我们可以通过清除iOS应用中的Cookie来解决问题。

[[NSHTTPCookieStorage sharedHTTPCookieStorage] removeCookiesSinceDate:[NSDate dateWithTimeIntervalSince1970:0]];

答案 2 :(得分:0)

加百列的回答对我来说只起到部分作用。问题在于,用户在调用AuthorizationsController#new之后直接注销,因此后续的AuthorizationsController#create请求在用户首次授权应用程序时是必需的。

为了使Authorization流程正常工作,我只需要在create动作之后或在无需进行应用授权的情况下在authorize#new之后注销用户。

class AuthorizationsController < Doorkeeper::AuthorizationsController

  def create
    redirect_or_render authorize_response
    # Sign out the user user clicked "Authorize" in the Authorize application page
    warden.logout
  end

  private

  def render_success
    if skip_authorization? || matching_token?
      redirect_or_render authorize_response
      # sign out directly if there is no need for authorizing the app
      warden.logout
    elsif Doorkeeper.configuration.api_only
      render json: pre_auth
    else
      render :new
    end
  end
end

请注意,此案例是与移动应用程序一起用作客户端的,如果要为多个应用程序使用SSO,将无法使用。

我使用Doorkeeper 5.1并设计了4.7,因此对于其他版本可能看起来有些不同。