Токен доступа в апи вконтакте

У меня есть приложение rails с авторизацией через devise и omniauth-vk. Это код в omniauth_callbacks_controller.rb

Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def vkontakte
binding.pry
@user = User.from_omniauth(request.env["omniauth.auth"])
token = request.env["omniauth.auth"]["credentials"]["token"]
current_user.token = @vk.token
current_user.vk_id = @vk.user_id
current_user.save

@vk = VkontakteApi::Client.new(current_user.token)

if @user.persisted?
  sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
  set_flash_message(:notice, :success, :kind => "vkontakte") if is_navigational_format?
else
  session["devise.vkontakte_data"] = request.env["omniauth.auth"]
  redirect_to new_user_registration_url

    if request.env["omniauth.auth"].info.email.blank?
      redirect_to "/users/auth/vkontakte?auth_type=rerequest&scope=email"
    end
  end
end

Я хочу связать текущего аутентифицированного пользователя с его токеном, но не знаю как. Когда я тестирую строку pry current_user.token = @vk.token, у меня возникает следующее исключение:

 NoMethodError: undefined method `token' for nil:NilClass
 from (pry):11:in `vkontakte'

person basania    schedule 01.10.2015    source источник


Ответы (1)


Вам не кажется, что вы определили @vk не в том месте?? проверьте этот код.

Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def vkontakte

@user = User.from_omniauth(request.env["omniauth.auth"])
token = request.env["omniauth.auth"]["credentials"]["token"]
@vk = VkontakteApi::Client.new(current_user.token)

current_user.token = @vk.token
current_user.vk_id = @vk.user_id
current_user.save

if @user.persisted?
  sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
  set_flash_message(:notice, :success, :kind => "vkontakte") if is_navigational_format?
else
  session["devise.vkontakte_data"] = request.env["omniauth.auth"]
  redirect_to new_user_registration_url

    if request.env["omniauth.auth"].info.email.blank?
      redirect_to "/users/auth/vkontakte?auth_type=rerequest&scope=email"
    end
  end
end
person Arvind    schedule 01.10.2015
comment
Боюсь, это немного сложнее. У него есть циклическая ссылка, так как current_user.token получает @vk.token присвоенное значение. И @vk инициализируется с помощью current_user.token. Может быть, для инициализации нужно использовать переменную token, это разорвет круг? - person The Ancient; 01.10.2015
comment
@Arv У меня снова та же проблема. - person basania; 01.10.2015
comment
@TheAncient Похоже, вы правы, но я новичок в Rails. Было бы неплохо, если бы вы могли помочь мне с этим кодом. Спасибо! - person basania; 01.10.2015
comment
@basania, как я уже сказал, мое первое впечатление, что вы должны позвонить @vk = VkontakteApi::Client.new(token). Посмотрите на метод initialize метода VkontakteApi::Client, если он устанавливает токен внутри аргумента и позволяет получить его с помощью метода #token, это то, что вам нужно. - person The Ancient; 01.10.2015
comment
@TheAncient Я проверил это. Я получил это. [7] pry(#<Users::OmniauthCallbacksController>)> @vk = VkontakteApi::Client.new(token) => #<VkontakteApi::Client:0x007fbe39953720 @token=nil> - person basania; 01.10.2015
comment
Разве token не nil перед звонком? - person The Ancient; 01.10.2015
comment
@TheAncient Это ноль ;( - person basania; 01.10.2015
comment
Затем проверьте возвращенный хэш omniauth/vk, распечатайте его и проверьте, получаете ли вы правильные значения с правильными ключами здесь: request.env["omniauth.auth"]["credentials"]["token"]... и если вы вообще получаете что-либо в from_omniauth call - person The Ancient; 02.10.2015
comment
@TheAncient Я получаю свой токен от request.env["omniauth.auth"]["credentials"]["token"]. От User.from_omniauth(request.env["omniauth.auth"]) я получаю хэш. Как я могу решить мою проблему? - person basania; 02.10.2015
comment
@basania Что вы получаете в request.env["omniauth.auth"]? Что вы получаете от звонка User.from_omniauth(request.env["omniauth.auth"])? И учтите, что я не могу отлаживать ваш код и исправлять проблему, я (и все в SO) могу только помочь найти путь к решению :) Вы должны сначала понять, как работает OAuth2, затем как работает omniauth, затем как vk занимается этим... Извините, если это звучит поучительно, но другого выхода нет - person The Ancient; 02.10.2015
comment
@TheAncient спасибо за вашу помощь. Я буду читать об этих технологиях/драгоценных камнях. - person basania; 02.10.2015