Android/iOS client sends to server API access_token and message.
I'm trying to share but with no luck, google responses with 'Invalid credentials'.
I was trying to add requestvisibleactions to client:
client = Google::APIClient.new(requestvisibleactions: ['https://schemas.google.com/AddActivity'])
And same to client.execute.
class GoogleSharer
def self.share(access_token, message, resource)
client = Google::APIClient.new
client.authorization.update_token!(access_token: access_token)
plus = client.discovered_api('plus', 'v1')
moment = {
type: ['http://schemas.google.com/AddActivity'],
target: { name: message, url: get_resource_url(resource) }
}
response = client.execute(api_method: plus.moments.insert, parameters: {collection: 'vault', userId: 'me'}, body_object: moment).body
a = 10
end
end
Please advise. Thanks.
Related
I'm new to Ruby and I'm trying to implement a oauth2 with client credentials flow.
I've found the "ouath2" gem, but that requires a redirect_uri that I don't have.
Here is the gem.
Here is what I'm trying to implement
secret_id = 'this-is-a-secret-id'
token_id = 'this-is-a-token-id'
scope = 'such-a-good-scope'
grant_type = 'client_credentials'
#client = nil
# Get access token
def GetAccessToken
HttpRequest request = HttpRequest::Post("https://awesome-page.com/oauth/token")
request.content = {
{ "client_id" => token_id },
{ "client_secret" => secret_id }
{ 'grant_type' => grant_type },
{ 'scope' => scope}
}
response = request.send
json = response.content
accessToken = JsonConvert.DeserializeObject<Token>(json)
#client = Client.new(bearer: accessToken)
end
# Refresh token
def RefreshToken
HttpRequest request = HttpRequest::Post("https://awesome-page.com/oauth/token")
request.content = {
{ "client_id" => token_id },
{ "client_secret" => secret_id }
{ 'grant_type' => grant_type },
{ 'refresh_token' => scope}
}
response = request.send
json = response.content
accessToken = JsonConvert.DeserializeObject<Token>(json)
#client = Client.new(bearer: accessToken)
end
# End then implementing the "getting the resources with the client" part and so on...
Any idea how to do this, I'm getting a little bit desperate now
Any help is greatly appreciated!
You’re kind of going about this all wrong. With the Oauth2 gem you need to:
Initialise a new Oauth2::Client with your client ID, secret, scope, and define the token and redirect url (this is a url in your app that users logging in get sent back to. Not used for Client Credentials flow as it’s for server to server comms)
Call token = client.client_credentials.get_token. This sets token to an AccessToken it obtained.
Then call token.get(‘https://your-url.com/path/to/resource’) - or post/patch/delete.
Look at the access_token.rb file in the repo to see the methods you can call. They also take a series of params, for things like additional headers or body payload you can pass. It’s based on Faraday so you can always look up Faraday docs for help with that part.
I am trying to call another API inside Bluemix or any other HTTPS post method using a gateway script inside IBM Bluemix (API Connect) using the code below:
var urlopen = require('urlopen');
var options = {
target: 'https://pokemons.mybluemix.net/api/pokemons/1',
method: 'POST',
headers: {},
contentType: 'application/json',
timeout: 60,
data: {"Message": "DataPower GatewayScript"}
};
urlopen.open(options, function(error, response) {
if (error) {
// an error occurred during the request sending or response header parsing
session.output.write("urlopen error: "+JSON.stringify(error));
} else {
// get the response status code
var responseStatusCode = response.statusCode;
var responseReasonPhrase = response.reasonPhrase;
console.log("Response status code: " + responseStatusCode);
console.log("Response reason phrase: " + responseReasonPhrase);
// reading response data
response.readAsBuffer(function(error, responseData){
if (error){
throw error ;
} else {
session.output.write(responseData) ;
apim.output('application/json');
}
});
}
});
But I am getting the following error:
{
"httpCode": "500",
"httpMessage": "Internal Server Error",
"moreInformation": "URL open: Cannot create connection to 'https://pokemons.mybluemix.net/api/pokemons/1', status code: 7"
}
Looks like there is some issue with the SSL Connections. If so, how can I get the SSL Details for the default Sandbox Catalog in IBM Bluemix API Connect? Or, how can I make the HTTPS POST calls to the above sample URL?
Since Version 5.0.6:
IBM API Connect 5.0.x
Forward SSLProxy (and Crypto) is replaced with SSLClient. These new profiles support ephemeral ciphers (DHE and ECDHE), perfect forward secrecy, and Server Name Indication (SNI) extension. Note that DHE ciphers in DataPower SSLServerProfile use 2048-bit DH parameters (as server) and accept 1024-bit DH parameters (as client).
In order for you specific example to work on API Connect using HTTPS you need to specify the sslClientProfile.
For example:
var urlopen = require('urlopen');
var options = {
target: 'https://pokemons.mybluemix.net/api/pokemons/1',
method: 'POST',
headers: {},
contentType: 'application/json',
timeout: 60,
sslClientProfile: 'webapi-sslcli-mgmt',
data: {"Message": "DataPower GatewayScript"}
};
I'm building a Slack bot, with a backend Sinatra app. The function of the bot is to add and read entries from Google Calendar.
I'm using session and environment variables.
I'm unable to open up the authorization webpage for Oauth and get access to user's Calendar data. Please help!
Here's my code:
#The redirect_url entered in Google Console.
#Google Oauth redirects to this endpoint once user has authorised request.
get '/oauthcallback' do
client = Signet::OAuth2::Client.new({
client_id: ENV['CALENDAR_CLIENT_ID'],
client_secret: ENV['CALENDAR_CLIENT_SECRET'],
authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
redirect_uri: "https://agile-stream-68169.herokuapp.com/oauthcallback",
code: params[:code]
})
response = client.fetch_access_token!
session[:access_token] = response['access_token']
redirect url_for(:action => :calendars)
end
#The Authorization url which checks if credentials are valid.
get '/authorize' do
# NOTE: Assumes the user is already authenticated to the app
user_id = request.session['user_id']
credentials = authorizer.get_credentials(user_id, request)
if credentials.nil?
redirect authorizer.get_authorization_url(login_hint: user_id, request: request)
end
end
#METHOD: Initialising the API by creating a Calendar Service
def intialize_api
$service = Google::Apis::CalendarV3::CalendarService.new
$service.client_options.application_name = ENV['CALENDAR_APPLICATION_NAME']
$service.authorization = auth_calendar
end
def auth_calendar
client = Signet::OAuth2::Client.new({
client_id: ENV['CALENDAR_CLIENT_ID'],
client_secret: ENV['CALENDAR_CLIENT_SECRET'],
authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
scope: Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY,
redirect_uri: "https://agile-stream-68169.herokuapp.com/oauthcallback"
})
redirect client.authorization_uri.to_s
end
I using oauth-ruby gem for a while, and I already implemented 2 types of auth:
default one
and custom, which uses OTP sent via sms
Both of them works perfectly now
But now i'm trying to implement new(3) 2-legged oauth. And I ran in to issues which I actually can't understand.
All my signed requests using access token from (3) are failing because of invalid token. For (1-2) it works without any issues.
Signing requests is implemented via RestClient.before_execution_proc:
RestClient.add_before_execution_proc do |req, params|
access_token.sign!(req)
end
I suppose the problem comes from access_token = OAuth::AccessToken as there actual difference between other 2.
Any suggestions or advices will be very helpful
1.
def default_oauth(login, pass, device: Device.new)
#cookies = login_req(login, pass).cookies
headers = common_headers.merge("Cookie" => #cookies)
#Get request token
request_token = consumer.get_request_token
# Authorize request key
authorize = RestClient.post(base_url + '/oauth/authorize',
{ requestToken: request_token.token, authorize: 'Authorize'},
headers) {|response, request, result| response }
auth_url_resp = RestClient.get(authorize.headers[:location], headers: headers) {|response, request, result| response }
# Get Access key
access_token = request_token.get_access_token
end
2.
def custom_oauth(phone, pin, otp: nil, device: Device.new)
otp = phone.to_s[-5..-1] if otp.nil?
resp = RestClient.post("#{base_url}/rest/smartphone/otp/sms-sender/#{phone}", '', common_headers) {|response, request, result| response }
request_token = consumer.get_request_token
payload = {
device: device.to_h,
otp: otp,
password: pin.to_s,
requestToken: request_token.token
}
headers = json_headers.merge('Cookie' => otp)
authorize = RestClient.post(base_url + '/oauth/otp-authorization',
payload.to_json, headers) {|response, request, result| response }
#access_token = request_token.get_access_token
end
3.
def new_oauth(login, pass, entry, device: Device.new)
tkn = consumer.get_request_token.token
payload = {
username: login,
password: pass.to_s,
requestToken: tkn,
entryPoint: entry,
device: device.to_h
}
headers =json_headers(device.id)
resp = RestClient.post("#{base_url}/oauth/login-authorization", payload.to_json, headers) {|response, request, result| response}
hsh ={oauth_token: resp.headers[:accesstoken], oauth_token_secret: resp.headers[:tokensecret] }
access_token = OAuth::AccessToken.from_hash(consumer, hsh)
end
Consumer:
def consumer
#consumer ||= build_consumer
end
def build_consumer
key = 'key_string'
secret ='secret_string'
OAuth::Consumer.new(key, secret, :site => base_url)
end
Issue was related to server (Spring) encoding stuff. oauth-ruby gem is escaping token secret (Combined secret or Encryption key) which is used for signature creation. Spring by default doing the same on server side.
Unescaping access_token.secret fixed this issue:
access_token.secret = OAuth::Helper.unescape(access_token.secret)
I'm trying to use the google-api-client gem to access the Google Search API for Shopping. Unfortunately, I can't seem to authenticate despite creating an access_token through the Google APIs Console.
Here is my code:
client = Google::APIClient.new
client.authorization.access_token = "<MY_CONSOLE_ACCESS_TOKEN>"
client.authorization.scope = "https://www.googleapis.com/auth/shoppingapi"
shopping = client.discovered_api("shopping", "v1")
response = client.execute(api_method: shopping.products.list,
parameters: { source: "public" })
When I view response.data, I see an error message though:
#<Google::APIClient::Schema::Shopping::V1::Products:0x809d6e14 DATA:{"error"=>{"errors"=>[{"domain"=>"global", "reason"=>"authError", "message"=>"Invalid Credentials", "locationType"=>"header", "location"=>"Authorization"}], "code"=>401, "message"=>"Invalid Credentials"}}>
What am I doing wrong?
Of course I figure it out minutes after posting. I'll share what worked for anyone else who has the same question.
client = Google::APIClient.new(authorization: nil)
shopping = client.discovered_api("shopping", "v1")
response = client.execute(key: "<MY_ACCESS_TOKEN>",
api_method: shopping.products.list,
parameters: { source: "public", country: "US" })