ruby-on-rails – 门卫/ oauth /令牌 – 空白响应
我在AngularJS中有一个前端,在RoR中有后端与Devise Doorkeeper RocketPants.
现在我已正确使用CORS,我可以成功地从我的API获取json响应(如果我关闭门卫保护).但是现在我正在尝试实现用户密码凭证流程: 在门卫上: resource_owner_from_credentials do |routes| request.params[:user] = {:email => request.params[:username],:password => request.params[:password]} request.env["devise.allow_params_authentication"] = true request.env["warden"].authenticate!(:scope => :user) end 在angularjs(src:nils-blum): var payload = "username="+username+"&password="+password+"&" + "client_id="+client_id+"&client_secret="+client_secret+ "&grant_type=password" $http({method: 'POST',url: scope.booksh_server + '/oauth/token',data: payload,headers: {'Content-Type':'application/x-www-form-urlencoded'} } ).success(function (data) { tokenHandler.set(data.access_token); scope.$broadcast('event:authenticated'); }); 注意:Nils的方法使用有效载荷作为对象与params,而不是字符串.在我的情况下,它给我带有效负载的POST,而不是FORM params,因此不起作用. 当我输入错误的用户/密码时,rails log说: Started POST "/oauth/token" for 127.0.0.1 at 2013-11-22 15:21:08 +0400 Doorkeeper::Application Load (0.5ms) SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."uid" = '981d6d654f5e709b2ca3437401c993a6d09cc91cc3fb16b8e2b3191e6421029c' AND "oauth_applications"."secret" = 'f92c4ec969525352bd03ec1eb810a9952cd0814d37ce5b2b02e8a928b2561e10' ORDER BY "oauth_applications"."id" ASC LIMIT 1 User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'undefined' ORDER BY "users"."id" ASC LIMIT 1 Chrome开发工具会将此请求显示为已取消. Firebug显示302 Found状态的空响应.当我从chrome REST App执行相同的POST时,UPD:服务器执行相同的操作,然后我获得302 Found,然后将其重定向到sign_in页面. 此外,如果我输入正确的用户/密码,firefox显示空响应200 OK,REST接收带有访问令牌的正确json,chrome显示取消响应并抛出CORS错误: XMLHttpRequest cannot load http://0.0.0.0:3000/oauth/token. Origin http://0.0.0.0:9000 is not allowed by Access-Control-Allow-Origin. 服务器日志: Started POST "/oauth/token" for 127.0.0.1 at 2013-11-22 15:33:22 +0400 Doorkeeper::Application Load (0.5ms) SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."uid" = '981d6d654f5e709b2ca3437401c993a6d09cc91cc3fb16b8e2b3191e6421029c' AND "oauth_applications"."secret" = 'f92c4ec969525352bd03ec1eb810a9952cd0814d37ce5b2b02e8a928b2561e10' ORDER BY "oauth_applications"."id" ASC LIMIT 1 User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."email" = '123@gmail.com' ORDER BY "users"."id" ASC LIMIT 1 (0.2ms) BEGIN SQL (0.4ms) UPDATE "users" SET "last_sign_in_at" = $1,"current_sign_in_at" = $2,"sign_in_count" = $3,"remember_token" = $4,"updated_at" = $5 WHERE "users"."id" = 1 [["last_sign_in_at",Fri,22 Nov 2013 11:32:49 UTC +00:00],["current_sign_in_at",22 Nov 2013 11:33:23 UTC +00:00],["sign_in_count",24],["remember_token","N5sRI6vE7B6vRNUlih3G2Q"],["updated_at",22 Nov 2013 11:33:23 UTC +00:00]] (17.5ms) COMMIT (1.6ms) BEGIN Doorkeeper::AccessToken Exists (0.3ms) SELECT 1 AS one FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = '72dd81fd85b638fb14f9d081193b1eda0e58f85d6820718ab635fe195c36a689' LIMIT 1 SQL (0.3ms) INSERT INTO "oauth_access_tokens" ("application_id","created_at","expires_in","resource_owner_id","scopes","token") VALUES ($1,$2,$3,$4,$5,$6) RETURNING "id" [["application_id",1],["created_at",["expires_in",7200],["resource_owner_id",["scopes",""],["token","72dd81fd85b638fb14f9d081193b1eda0e58f85d6820718ab635fe195c36a689"]] (28.1ms) COMMIT 我怎样才能做到这一点?我需要POST / oauth / token来处理身份验证,并在电子邮件/密码正确的情况下使用access_token进行响应. 解决方法
好极了!最后我做到了.仍然不知道为什么在整个网络的教程中它更容易.
所以,问题来自:在我的ApplicationController(根目录,而不是处理API的那个)中,我有以下内容用于CORS: before_filter :set_headers def set_headers headers['Access-Control-Allow-Origin'] = 'http://0.0.0.0:9000' headers['Access-Control-Allow-Methods'] = 'GET,POST,PATCH,PUT,DELETE,OPTIONS,HEAD' headers['Access-Control-Allow-Headers'] = '*,X-Requested-With,Content-Type,If-Modified-Since,If-None-Match' headers['Access-Control-Max-Age'] = '86400' end 深入研究这个问题我发现当我调用/ oauth / token时没有调用这个函数,但是当我去API之外的任何其他路径时调用它,这个路径是用ApplicationController处理的 门卫有自己的控制器独立于您的应用程序控制器.文档描述了他们的行为改变(link),所以这是帮助我的原因: routes.rb中: use_doorkeeper do controllers tokens: 'custom_tokens' end custom_tokens_controller.rb: class CustomTokensController < Doorkeeper::TokensController include AbstractController::Callbacks before_filter :set_headers def set_headers puts 'headers set' headers['Access-Control-Allow-Origin'] = 'http://0.0.0.0:9000' headers['Access-Control-Allow-Methods'] = 'GET,If-None-Match' headers['Access-Control-Max-Age'] = '86400' end end 重要的是将Callbacks包含到控制器中,因为Doorkeeper控制器是从Metal继承的,因此没有包含rails无法找到before_filter. 它现在看起来很好:它验证我的用户/密码对,并返回access_token(我希望,它的工作原理:D).如果出现问题,现在应该重定向.这是我知道解决的问题(自定义监管器故障),所以现在一切正常.咦!这很长…如果有人知道为什么基于互联网的食谱没有帮助,请发表您的想法=) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |