[英]Doorkeeper /oauth/token - blank response
I have a front-end in AngularJS and back-end in RoR with Devise + Doorkeeper + RocketPants. 我在AngularJS中有一个前端,在RoR中有后端与Devise + Doorkeeper + RocketPants。 For now I have properly working CORS, I can succesfully get json responses from my API (if I turn off doorkeeper protection).
现在我已正确使用CORS,我可以成功地从我的API获取json响应(如果我关闭门卫保护)。 But now I'm trying to implement user password credentials flow:
但是现在我正在尝试实现用户密码凭证流程:
On doorkeeper: 在门卫上:
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
On angularjs (src: nils-blum ): 在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');
});
Note: Nils's approach uses payload as object with params, not a string. 注意:Nils的方法使用有效载荷作为对象与params,而不是字符串。 In my case it gives me POST with payload, not with FORM params, and thus not working.
在我的情况下,它给我带有效负载的POST,而不是FORM params,因此不起作用。
When I enter wrong user/password, rails log says: 当我输入错误的用户/密码时,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 dev tools show this request as cancelled. Chrome开发工具会将此请求显示为已取消。 Firebug shows empty response with 302 Found status.
Firebug显示302 Found状态的空响应。 When I perform same POST from chrome REST App , UPD: server does the same, and I get 302 Found and then it's redirected to sign_in page of devise.
当我从chrome REST App执行相同的POST时,UPD:服务器执行相同的操作,然后我获得302 Found,然后将其重定向到devise的sign_in页面。
Moreover, if I enter correct user/password, firefox shows empty response with 200 OK, REST receives proper json with access token, and chrome shows cancelled response and throws CORS error: 此外,如果我输入正确的用户/密码,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.
Server log: 服务器日志:
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", Fri, 22 Nov 2013 11:33:23 UTC +00:00], ["sign_in_count", 24], ["remember_token", "N5sRI6vE7B6vRNUlih3G2Q"], ["updated_at", Fri, 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", Fri, 22 Nov 2013 11:33:23 UTC +00:00], ["expires_in", 7200], ["resource_owner_id", 1], ["scopes", ""], ["token", "72dd81fd85b638fb14f9d081193b1eda0e58f85d6820718ab635fe195c36a689"]]
(28.1ms) COMMIT
How can I make this work? 我怎样才能做到这一点? I need POST /oauth/token to process authentication and respond with access_token in case email/password were correct.
我需要POST / oauth / token来处理身份验证,并在电子邮件/密码正确的情况下使用access_token进行响应。 Any help is appreciated, I'm tired of being stuck at this )
感谢任何帮助,我已经厌倦了被困在这里)
Yay! 好极了! Finally I made it work.
最后我做到了。 Still dunno why in tutorials all over the web it's much easier.
仍然不知道为什么在整个网络的教程中它更容易。
So, where the problem comes from: in my ApplicationController
(root one, not the one that handles API) I had following for CORS: 所以,问题来自:在我的
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
Digging into the problem I've found that this function is not called when I call /oauth/token but is called when I go to any other route outside of API which is processed with ApplicationController
深入研究这个问题我发现当我调用/ oauth / token时没有调用这个函数,但是当我去API之外的任何其他路径时调用它,这个路径是用
ApplicationController
处理的
Doorkeeper has its own controllers independent from your app controller. 门卫有自己的控制器独立于您的应用程序控制器。 Docs describes changing of their behavior well ( link ), so here is what helped me:
文档描述了他们的行为改变( 链接 ),所以这是帮助我的:
routes.rb: routes.rb中:
use_doorkeeper do
controllers tokens: 'custom_tokens'
end
custom_tokens_controller.rb: 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, 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
end
Important thing is to include Callbacks
into controller, as Doorkeeper controllers are inherited from Metal
, so without inclusion rails can't find before_filter
. 重要的是将
Callbacks
包含到控制器中,因为Doorkeeper控制器是从Metal
继承的,因此没有包含rails无法找到before_filter
。
It looks good now: It authenticates my user/password pair, and returns access_token (I hope, it works :D ). 它现在看起来很好:它验证我的用户/密码对,并返回access_token(我希望,它的工作原理:D)。 If something is wrong, now there should come redirect.
如果出现问题,现在应该重定向。 This is the problem which I know solution to (custom warden failure), so everything is OK now.
这是我知道解决的问题(自定义监管器故障),所以现在一切正常。 Huh!
咦! It was long... If anyone knows why internet-based recipes didn't help, please post your thoughts =)
这很长...如果有人知道为什么基于互联网的食谱没有帮助,请发表您的想法=)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.