如何将门卫访问令牌作为json返回

我正在尝试为iOS应用程序创建一个登录系统,其中导轨后端由设备和门卫提供支持。

我想限制网络请求的数量,因此不希望必须从凭证中获取令牌,然后将用户详细信息作为单独的请求获取。

这是我目前的尝试:

token = Doorkeeper::AccessToken.create!(application_id: @application_id, resource_owner_id: current_user.id, :expires_in => 168.hours) puts token.token render :json => {:user => current_user, :token => token.as_json(:include=> token)}, status: :ok, location: :users 

然而,返回的是:

 {"user":{"id":2,"email":"user3@test.com","created_at":"2014-06-12T17:25:12.000Z", "updated_at":"2014-06-13T12:20:18.536Z", "firstName":"user","lastName":"test","subscription":null}, "token":{"resource_owner_id":2,"scopes":[],"expires_in_seconds":604800, "application":{"uid":"[Filtered]"}}} 

因此,实际的access_token密钥不会被传回以允许我进行将来的调用。 我可以看到在DoorKeeper::AccessToken.as_json没有返回令牌本身,但token.as_json(:include=> token)仍然没有返回它。

有谁知道如何返回AccessToken,包括访问令牌本身,如json?

我处理这个的方法是创建一个自定义令牌控制器并覆盖令牌请求操作。 在那里,我可以添加自定义的东西来回应。

 # app/controllers/custom_tokens_controller.rb class CustomTokensController < Doorkeeper::TokensController # Overriding create action # POST /oauth/token def create response = strategy.authorize body = response.body if response.status == :ok # User the resource_owner_id from token to identify the user user = User.find(response.token.resource_owner_id) rescue nil unless user.nil? ### If you want to render user with template ### create an ActionController to render out the user # ac = ActionController::Base.new() # user_json = ac.render_to_string( template: 'api/users/me', locals: { user: user}) # body[:user] = Oj.load(user_json) ### Or if you want to just append user using 'as_json' body[:user] = user.as_json end end self.headers.merge! response.headers self.response_body = body.to_json self.status = response.status rescue Doorkeeper::Errors::DoorkeeperError => e handle_token_exception e end end 

只需确保在routes.rb指向此控制器

 # routes.rb Rails.application.routes.draw do # Doorkeeper use_doorkeeper do controllers :tokens => 'custom_tokens' end # Your other routes here... end 

这是经过测试的,它可以工作,我在我的项目中使用它。

我设法解决这个问题的方法是创建我自己的AccessToken类,它重载as_json方法以包含我想要的字段。

例如

 class AccessToken < Doorkeeper::AccessToken def as_json(options={}) { :token => self.token, #:resource_owner_id => self.resource_owner_id, #:scopes => self.scopes, :created_at => self.created_at, :expires_in_seconds => self.expires_in_seconds, #:application => { :uid => self.application.uid } } end end 

如果有人有更好的解决方案,我会全力以赴

我知道这已经解决了一段时间了。 我最近想在我的API上实现相同的行为,我依靠模型关联来实现它:

 class User < ActiveRecord::Base has_one :token, -> { order 'created_at DESC' }, class: Doorkeeper::AccessToken, foreign_key: :resource_owner_id end 

然后使用序列化器:

 class UserSerializer < ActiveModel::Serializer attributes :id, :name, :email has_one :token, serializer: AccessTokenSerializer end class AccessTokenSerializer < ActiveModel::Serializer attributes :token, :expires_in_seconds end 

您只需将数据返回为:

 class DummyController < ApplicationController def dummy respond_with current_user, status: :ok end end 

这将输出一个看起来像这样的JSON:

 { "id": 17, "name": "Chuck Norris", "email": "chuck@norr.is", "token": { "token": "c62af258f2d1ac816f65606a2a8413b8e0c2ad5b4434f9c75b56765f54ee627b", "expires_in_seconds": "5427" } } 

实际上我们可以获得访问令牌:

 doorkeeper_token.token 

你可以把它包含在json响应中,这样你就不需要在门卫本身内编辑任何东西了。
但是,在将它包含在json响应中之前不要忘记添加一些条件,因为它总是在响应中显示它似乎不太好。