Session lost after redirect_to - session

I am having problems with the session being lost after a redirect in my application. We are using the gem "Koala" to integrate with Facebook. This gem was working fine with Rails 3.0, but not we have upgraded to Rails 3.2.12 and it's failing because the session vanishes after the redirect to Facebook.
I have been investigating and reading a lot about similar problems, but could not get any solution yet. The key here are 2 actions:
1) Publish_event action, where we set the Koala object and connect with Facebook:
def publish_event
...
...
callback = url_for(......................)
#oauth = Koala::Facebook::OAuth.new(Facebook::APP_ID, Facebook::SECRET, callback)
session[:oauth] = #oauth
redirect_to #oauth.url_for_oauth_code(:permissions => ["offline_access", "publish_stream", "manage_pages"])
end
That part works fine and connects to Facebook successfully. Facebook redirects back to our application, and the second action is called:
2) Facebook callback action, where we post the message that we want:
def facebook_callback
token = session[:oauth].get_access_token(params[:code])
#graph = Koala::Facebook::API.new(token)
.....
end
The problem here is that after the redirection to Facebook, the session is not loaded (Rack::Session::Abstract::SessionHash:0x30027e4 not yet loaded), so we can not continue, as we need the original oauth Koala object that created the connection with Facebook and that should be in the session.
I have the sessions configured as an active_record_store, and it works well in the rest of the application, so I am very confused here.
Anyone has come across anything similar ? OR do you have any suggestion how to do this differently ?
Thanks !

Related

Expected top level property 'installed' or 'web' to be present. google-apis-ruby quickstart

I have been attempting to get device information using the google/apis/admin_directory_v1 api.
I found a ruby quickstart that happens to use this exact api in the example. However when I follow the instructions and try to run the script that is listed in the link I get the error ...
"Expected top level property 'installed' or 'web' to be present."
A link to the quickstart is below.
EDITED SORRY I WAS OVER TIRED LOL
https://developers.google.com/admin-sdk/directory/v1/quickstart/ruby
I have been trying to return results from the API all day and it has pushed me to write this post. Please don't attack me I am merely trying to help someone else in the future with this because the documentation is very cavernous for something as simple as api requests?
Anyway I have no idea what the error means or how to proceed. I have fixed enough errors with this situation for one night and now I am just hoping to meet someone else who has traveled this road.
Edited: Sorry to post the wrong link I was too tired. I was never using anything related to the sheets link I must have had the tab open for researched and just pasted the wrong link.
Edited Again: I have gotten a bit further but still no success... Well actually I take that back I am geting a confirmed bearer token back I am just unsure how to use it properly with this api client... The test I am currently working with is below...
require "google/apis/admin_directory_v1"
require "googleauth"
require "googleauth/stores/file_token_store"
require "fileutils"
APPLICATION_NAME = "Directory API Ruby Quickstart".freeze
CREDENTIALS_PATH = "credentials.json".freeze
CUSTOMER_ID = "xxxxxxx".freeze
SCOPE = Google::Apis::AdminDirectoryV1::AUTH_ADMIN_DIRECTORY_USER_READONLY
def authorize
authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: File.open('credentials.json'),
scope: SCOPE)
authorizer.fetch_access_token!
end
# puts authorize
# Initialize the API
service = Google::Apis::AdminDirectoryV1::DirectoryService.new
service.client_options.application_name = APPLICATION_NAME
service.authorization = Google::Auth.get_application_default(SCOPE)
response = service.list_mobile_devices(customer_id: CUSTOMER_ID)
puts response.to_json
This is returning the error below
/var/lib/gems/2.7.0/gems/google-apis-core-0.4.2/lib/google/apis/core/http_command.rb:229:in `check_status': PERMISSION_DENIED: Request had insufficient authentication scopes. (Google::Apis::ClientError)
I would assume that this should be possible with a service account and that I am still making a simple mistake....
The issue you are having is that the Ruby quickstart for Google sheets was designed for use with an installed application.
You are directed to create installed credentials. Here is a video as well How to create Google Oauth2 installed application credentials.json.
Authorization credentials for a desktop application. To learn how to create credentials for a desktop application, refer to Create credentials.
This error message is telling you that you did not create that type of credentials. Did you try to create service account credentials maybe? That wont work with this code.

URL's for using Xamarin.Auth with Facebook

I'm trying to test out Xamarin.Auth with Facebook on Xamarin.iOS. I can login via the web view and get redirected but the Completed handler is never called. After some investigation, it looks like a common problem that users have is with this code from WebRedirectAuthenticator.cs
private bool UrlMatchesRedirect (Uri url)
{
return url.Host == redirectUrl.Host && url.LocalPath == redirectUrl.LocalPath;
}
which controls whether the Completed event is raised.
As far as I can tell I have everything set up correctly both in code and in the Facebook developer console.
Redirect URL's in Facebook developer console
URL's
Authenticator
However, the process never continues past this point
When you are testing are you using the same account as the Facebook app / developer account is setup on? If so try testing with a normal account.
I could be wrong but have a vague memory or hitting something similar once
Try removing the s from "https". Your variable declaration should look like this:
FACEBOOK_REDIRECT_URL = "http://www.facebook.com/connect/login_success.html"

Google Authentication using django-rest-framework and python-social-auth

Question in short: Login with DRF, python-social-auth and Angularjs works with Facebook but not Google.
I'm building a django app that needs to enable users to signup/login via Facebook and Google in addition to locally stored email/password combo. It works as follows:
For both signup and login, Angularjs initiates FB and google apis (FB.init and gapi.auth2.init) with their respective app_ids. All js libraries required for this are included in the pages.
Based on user's selection, both pages let user to log in using Facebook or google or let them enter their email/password combo.
All required info including their access_token is collected via FB or Google's API.
When user submits the form after filling up all relevant details (signup requires them to enter some additional data), the data including the access_token is sent to the server by an AJAX request.
At the server side, class based views, LoginView and SignUpView, accepts the requests and processes them. Email-based signup/login is directly handled by the code. Google/FB based signup/login is passed to python-social-auth's do_auth function for authentication.
When provider chosen is facebook, this works fine. When, it's Google (Tried both google-oauth2 and google-plus), do_auth eventually raises a 403 Forbidden error. When the related url, https://googleapis.com/plus/v1/people/me?access_token=ACCESS_TOKEN&alt=json is copied to the browser, it shows an error message:
Daily Limit for Unauthenticated Use Exceeded. Continued use requires
signup
I've made sure of the following things:
Enabled Google+ API in the google developer console for the corresponding app
From the google developer console, added http://localhost:5001 to javascript origin field and http://localhost:5001/social/complete to redirect uri field (Latter field is filled up later. Same result with or without it.)
Generated key and copied client_id and client_secret to settings.SOCIAL_AUTH_GOOGLE_OAUTH2_KEY and settings.SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET. Double checked their accuracy.
Added 'social.backends.google.GoogleOAuth2' to settings.AUTHENTICATION_BACKENDS. Tried placing here both GoogleOAuth2 and GooglePlus together and separately.
Tried all these in 2-3 with PLUS also, instead of OAUTH2. Still the same result.
Tried again after setting, settings.SOCIAL_AUTH_USE_DEPRECATED_API as True. This also fails but the error is now 401.
What to do next to get this working with Google authentication too? Gone through many other similar questions here and issues reported in Github.
Here's the relevant code:
class SignUpView(CreateAPIView):
def create(self, request, *args, **kwargs):
provider = request.data['provider']
strategy = load_strategy(request)
backend = load_backend(strategy=strategy, name=provider, redirect_uri=None)
token = request.data['access_token']
try:
user = backend.do_auth(token, user=None, **data)
except AuthAlreadyAssociated:
pass
I've recently struggled with similar problem, but my situation was a little bit different because I'm using django-rest-framework-social-oauth2.
First of all I've noticed you enabled Google+ API, but:
Added 'social.backends.google.GoogleOAuth2' to settings.AUTHENTICATION_BACKENDS.
Try change your settings to (this is described in python social auth docs) :
AUTHENTICATION_BACKENDS = (
...
'social_core.backends.google.GooglePlusAuth',
)
SOCIAL_AUTH_GOOGLE_PLUS_KEY = '...'
SOCIAL_AUTH_GOOGLE_PLUS_SECRET = '...'
Another thing that can be useful for you is google oauth playground

How to let external API send POST without turning protect_from_forgery off?

I'm using Rails 4.1.0.
I am in a project were my options are very limited. I need to have a form submit data to an external API. I stored the values of the form in the session because this application is multi-form based.
The problem is that when the API POSTs back to my Rails application, the session is nullified.
I know this happens because protect_from_forgery in my app/controllers/application_controller.rb
How can I keep the session just a little longer, until the API POSTs back to my confirmation page (saying the form was submitted successfully)?
You can turn off request forgery protection for just a single action:
skip_before_action :verify_authenticity_token, only: :my_action_name
Replace :my_action_name with the name of the action the API POSTs back to.
Source: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html#method-i-protect_from_forgery

GitHub OAuth authorize request doesn't redirect to Authorize Application page

I've implemented my own classes for handling authorization via OAuth to GitHub using Faraday in Ruby. I've verified that under the following conditions:
Not logged into GitHub
No token exists for the app
that a request for authorization via GET to "/login/oauth/authorize" with a random state variable:
Redirects to the GitHub login page
Redirects to the Authorize Application page after login
Executes callback to my app with temporary code after authorizing
Responds with access_token when I POST to "/login/oauth/access_token" with temporary code
The problem I have is when I alter the first condition, I'm not already logged into GitHub. The same GET request is sent to GitHub, I see the correct URL with the right parameters. I then see what appears to be the correct redirect by GitHub with a return_to parameter, but it quickly just redirects again back to the GitHub home page.
I'm hoping it's something easy like forgetting a header parameter or something, and someone might spot the problem right away. Anyway, any help is appreciated...
Code to setup Faraday connection:
def connection
#connection ||= Faraday.new(url: 'https://github.com') do |faraday|
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
end
Code to send authorization request:
def request_authorization(client_id, redirect_uri, redirect_id, scope, expected_state)
response = connection.get '/login/oauth/authorize', {
client_id: client_id,
redirect_uri: "#{redirect_uri}?id=#{redirect_id}",
scope: scope,
state: expected_state
}
if response.status == 302
response.headers[:location]
else
nil
end
end
I didn't show the code, but my controller does a redirect to the URL reply from request_authorization(). Again, I definitely see the redirect from my controller in both cases, but the second case seems to encounter something GitHub didn't like in the redirected request. I assume it then redirects to the home page and never replies to my app because of this unknown problem in my original request.
Thanks,
David
Ivan from GitHub was a great help in finding the answer to my question. I had assumed the problem was some detail with using Faraday or OAuth, but it turns out the problem was a basic assumption that proved wrong. Hopefully this will help others that run into a similar misunderstanding.
I had assumed that a user of my app that wanted to connect to GitHub (or another OAuth service) would issue something like a "connect" request to my app. My app would then generate the OAuth authorization request to GitHub, handle any redirects, and eventually wind up presenting the Authorize App page to the user for acceptance.
Turns out I just needed to make the "connect" request actually a link to directly make the authorization request to GitHub. My app then only has to worry about handling the callback, which it already did. Easier and works in all cases now.
Turns out the wrong approach worked when not logged in due to it being the simple case. It failed when logged in because I wasn't handling session state that normally the browser would provide.
A more careful read of the OAuth RFC cleared up my confusion about where requests and responses are handled for the User Agent and for the Client.

Resources