Friday, May 5, 2017

Can't retrieve access_token, refresh_token from Omniauth authentication strategy with Devise, Rails 4

Leave a Comment

I am using such gems:

gem "omniauth-yandex" gem 'devise' 

My setup.

Routes:

 devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" } 

Devise initializer:

config.omniauth :yandex, Rails.application.secrets.client_id , Rails.application.secrets.password, callback_url: "http://cb2bcdc4.ngrok.io/users/auth/yandex/callback" 

User model:

devise :database_authenticatable, :registerable,          :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:yandex]      def self.from_omniauth(auth)         where(provider: auth.provider, uid: auth.uid).first_or_create do |user|         user.provider = auth.provider         user.uid = auth.uid         user.email =  auth.info.email         user.password = Devise.friendly_token[0,20]       end    end 

CallbackController:

class CallbacksController < Devise::OmniauthCallbacksController              def yandex        #empty     end end 

View:

  <%= link_to "Sign in with Yandex", user_yandex_omniauth_authorize_path, id: "sign_in" %> 

When I click "Sign in with Yandex" my application prompts for user permission and then redirects back to my application. User is created in my database with such fields-- e-mail,provider, uid. But I would like to have also access_token, refresh_token and expires_at because I am using few Yandex API's.

When I httlog'ed above action (From clicking "Sign in .." to the redirect back to my application) I received these results:

D, [2017-04-26T19:17:42.091838 #24865] DEBUG -- : [0;30;101m[httplog] Connecting: oauth.yandex.ru:443[0m D, [2017-04-26T19:17:42.266645 #24865] DEBUG -- : [0;30;101m[httplog] Sending: POST http://oauth.yandex.ru:443/token[0m D, [2017-04-26T19:17:42.267040 #24865] DEBUG -- : [0;30;101m[httplog] Data: client_id=097253682f9f41289ec5exxxxxxx&client_secret=xxxxxxdb4fxx0eadcbb8a4143&code=xxxxx327&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fcb2bcdc4.ngrok.io%2Fusers%2Fauth%2Fyandex%2Fcallback%3Fstate%xxxxxxxxxxx%26code%xxxx[0m D, [2017-04-26T19:17:42.410712 #24865] DEBUG -- : [0;30;101m[httplog] Status: 200[0m D, [2017-04-26T19:17:42.410945 #24865] DEBUG -- : [0;30;101m[httplog] Benchmark: 0.143445 seconds[0m D, [2017-04-26T19:17:42.411168 #24865] DEBUG -- : [0;30;101m[httplog] Response: {"token_type": "bearer", "access_token": "xxxxxxxxuyBwtcyAFjkBZo3F3MCiIaTI", "expires_in": 31528753, "refresh_token": "xxxxxxxxxxxClSH:Pts0u-Mfls-vdEc7-zTOod9ZWzegNFRxxxxxxxxxxxxxKHpwsqBFUHHKtg"}[0m D, [2017-04-26T19:17:42.414748 #24865] DEBUG -- : [0;30;101m[httplog] Connecting: login.yandex.ru:443[0m D, [2017-04-26T19:17:42.609376 #24865] DEBUG -- : [0;30;101m[httplog] Sending: GET http://login.yandex.ru:443/info?format=json[0m D, [2017-04-26T19:17:42.609720 #24865] DEBUG -- : [0;30;101m[httplog] Data: [0m D, [2017-04-26T19:17:42.675702 #24865] DEBUG -- : [0;30;101m[httplog] Status: 200[0m D, [2017-04-26T19:17:42.675972 #24865] DEBUG -- : [0;30;101m[httplog] Benchmark: 0.065791 seconds[0m D, [2017-04-26T19:17:42.676211 #24865] DEBUG -- : [0;30;101m[httplog] Response: {"first_name": "xxxxxxxxxxx9", "last_name": "xxxxxxxxxxxxxxx", "display_name": "xxxxx", "emails": ["xxxxxx@yandex.ru"], "default_email": "xxxxx@yandex.ru", "real_name": "xxxxxx2", "login": "xxxxxxx", "sex": "male", "id": "xxxx123"}[0m 

Question: How can I save access_token, refresh token from Omniauth authentication process to user as it is clearly visible (7th line ) that it does retrieve it using my client_id and secret without any of my code.

Thanks.

What I have tried:

Added user.access_token = auth.credentials.token to self.from_omniauth(auth) method in user model. But there wasn't any positive change.

UPDATE:

The same problem exists on different platforms. For example, on shared hosting and in Linux Ubuntu (completely fresh project from scratch).

1 Answers

Answers 1

The access token is provided by the yandex gem, or to be more specific, the omniauth-oauth2 gem.

Just get inside your controller by doing: request.env["omniauth.auth"].credentials.token

Boom. That's your access token. (refresh token and expiry data is also in the credentials hash, just print it out)

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment