2013-07-27 7 views
7

Miesiące temu stworzyłem aplikację szyn, która została uwierzytelniona za pomocą google przy użyciu oauth2 - w szczególności gemu omniauth-google-oauth2. Miałem wszystkie kroki, aby utworzyć uwierzytelnianie i przechowywać token odświeżania, ale ostatnio oauth2 przestał odsyłać "refresh_token" jako część odpowiedzi. Początkowo ja otrzymywał odpowiedź, która zawierała:Jak mogę odzyskać "refresh_token" dla aplikacji rails z omniauth google oauth2?

credentials: { 
    refresh_token: XXX, 
    token: YYY, 
    expires_at: 1374840767, 
    expires: true 
}, 

Teraz tylko wrócić token, który wygasa w ciągu godziny:

credentials: { 
    token: YYY, 
    expires_at: 1374840767, 
    expires: true 
}, 

ja naprawdę nie wiem, co zrobiłem po stronie aplikacji, aby zmień to, więc nie jestem pewien, czy coś zmieniło się w google, czy było to coś, co zrobiłem. Dla kontekście mój kod wygląda następująco:

inicjalizatorów/omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do 
    provider :google_oauth2, 'KEY', 'SECRET', {:scope => "userinfo.email,userinfo.profile,analytics.readonly,adsense.readonly"} 
end 

authentications_controller.rb gdzie otrzymam odpowiedź:

def create 
    auth = request.env["omniauth.auth"] 
    params = request.env["omniauth.params"] 
    project = Project.find(params['project_id']) 

    Authentication.create(:project_id => project.id, :provider => auth['provider'], :uid => auth['uid'], :access_token => auth['credentials']['refresh_token']) 
    flash[:notice] = "Authentication successful." 
    redirect_to owner_view_project_path(project) 
end 

to jest możliwe, że czegoś brakuje w mój plik initializers/omniauth.rb? Próbowałem dodanie poniższych opcji do mieszania, ale nie wydaje się, aby przywrócić token odświeżania:

:approval_prompt => "force", :access_type => "offline" 

Każda pomoc będzie bardzo mile widziane! Z góry dziękuję!

+0

Czy rozwiązałeś ten problem? Teraz mam ten sam problem i chciałbym zobaczyć twoje rozwiązanie. Dzięki! –

Odpowiedz

8

komunikat: 'zgoda' jest coraz Ci token odświeżania. Coś jak to powinno działać:

Rails.application.config.middleware.use OmniAuth::Builder do 
    scopes = [ 
     # we need the profile scope in order to login 
     "https://www.googleapis.com/auth/userinfo.profile", 
     # this and other scopes could be added, but match them up with the 
     # features you requested in your API Console 
     "https://www.googleapis.com/auth/calendar" 
    ] 

    provider :google_oauth2, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, { scope: scopes.join(" "), access_type: 'offline', prompt: 'consent'} 
end 
+0

Monit: "Zgoda" zrobił to dla mnie – okysabeni

+0

Dzięki zachęcie: "Zapisano mi zgodę" – chickensmitten

+0

Tło: Wygląda na to, że 'refresh_token' jest zawarty tylko wtedy, gdy użytkownik jawnie potwierdza dostęp (co zawsze dzieje się przy pierwszym żądaniu). Kolejne wnioski o autoryzację są automatycznie potwierdzane, ponieważ Google zapamiętał tę decyzję, jednak automatyczne potwierdzenie braku "refresh_token" (co ma sens). Ta odpowiedź mówi, jak wymusić zgodę, co zapewni obecność "refresh_token". Zwróć uwagę, że spowoduje to zapytanie użytkownika za każdym razem o potwierdzenie jego autoryzacji. – codener

2

Jak widzę, to wystarczy dodać

access_type: 'offline' 

do zakresu swojego dostawcy.

Sztuczka jest następująca w definicji Google: token odświeżania jest dostarczany dopiero po raz pierwszy, że twoja aplikacja uzyskuje dostęp do konta google.

Odmów zezwolenia i odzyskaj autoryzację, jeśli chcesz ponownie zobaczyć token odświeżania wysyłany przez google.

Zobacz google oryginalnej definicji tutaj: „Jeśli aplikacja wymaga odświeżenia tokeny dostępu, gdy użytkownik nie jest obecny w przeglądarce, a następnie użyć typ_dostępu. W trybie offline Spowoduje to w aplikacji uzyskania odświeżenie tokena pierwszy czas twoja aplikacja wymienia kod autoryzacyjny dla użytkownika. " (https://developers.google.com/identity/protocols/OAuth2WebServer)