I get: The security token included in the request is invalid
Where do I get a session token? The current documentation is confusing. On the one hand it says:
If you make a request using AWS::DynamoDB with long-term credentials a request is made to Amazon STS for temporary session credentials. These will be cached in the process and re-used.
and next it says:
Amazon DynamoDB requires that all requests are made with short-term credentials (e.g. requires a session token).
so exactly where does the session_token come from if I don't provide it? And if the call provides it, why would it be invalid?
requires 'aws-sdk'
cred = {:access_key_id => 'xxxx',
:secret_access_key => 'yyyy'}
#:session_token => ''}
ddb = AWS::DynamoDB.new(cred)
items = {...}
ddb.batch_write do |batch|
batch.put('my_mappings', items)
end
The documentation is incorrect/old (its been changed on the master branch in GitHub). You no longer require session credentials to use DynamoDB. You should be able to configure just your :access_key_id and :secret_access_key.
If you do want session credentials, you can get them from AWS::STS.
After some trial and error, I found that the following works.
cred = {:access_key_id => 'xxxx',
:secret_access_key => 'yyyy', :session_token => nil}
ddb = AWS::DynamoDB.new(cred)
In my original example, the ddb handle would work for certain operations but not for batch_write. Passing the 'nil' works. The documentation is unclear and the API is inconsistent in the current version.
Related
When doing GET /admin/webhooks.json it simply returns:
{"webhooks"=>[]}
I've created 8 webhooks using the admin panel but I can't seem to access them using the API. If I enter https://SHOP_NAME.myshopify.com/admin/webhooks.json directly into the browser it does return all the webhooks.
Here's the call I'm making using the credentials from a private app:
require 'httparty'
data = HTTParty.get("https://<API_KEY>:<PASSWORD>#<SHOP_NAME>.myshopify.com/admin/webhooks.json", :headers => {'Content-Type' => 'application/json'})
Any idea what I'm doing wrong?
Scanning through the Shopify API authentication docs doesn't give any indication that HTTP basic authentication of the form https://<API_KEY>:<PASSWORD>#... is supported.
This may be the reason why you can't query the hooks. In you browser you may use a web session. You can verify by removing the basic auth from the url and open again in you browser
https://<SHOP_NAME>.myshopify.com/admin/webhooks.json
The /admin/webhooks.json endpoint only returns the webhooks that you have registered with that API key. That's why I'm seeing an empty array.
The Stripe API reference says this about authentication:
The example they give is this:
require "stripe"
Stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
The sk_test_BQokikJOvBiI2HlWgH4olfQ2 secret key is found in the account settings on Stripe's webpage. I understand this is the secret api key for my application to talk with Stripe.
But then I read this documentation on getting started with Stripe Connect:
When using our official API libraries, we recommend that you pass in the
access_token with every request, instead of setting the API key globally.
This is because the access_token used in any API request depends on the user
you're charging on behalf of.
The example they give is:
# Not recommended: setting global API key state
Stripe.api_key = ACCESS_TOKEN
Stripe::Customer.create(
:description => "example#stripe.com"
)
# Recommended: sending API key with every request
Stripe::Customer.create(
{:description => "example#stripe.com"},
ACCESS_TOKEN # user's access token from the Stripe Connect flow
)
Here, the access token is returned to the application after a user has connected to the application through Stripe Connect. The access token can be used to perform actions on behalf of that user, like charging their card.
So, they pass the API key with every request, but why would the user's access token be an api key? I thought from the first documentation that the api key is supposed to be my application's secret api key? Instead, they are setting the user's access token. How will Stripe identify my application then if I'm setting the user's access token and not my own secret key?
Then, I read their example on integrating Stripe Checkout with Sinatra. The code sample they give is:
require 'sinatra'
require 'stripe'
set :publishable_key, ENV['PUBLISHABLE_KEY']
set :secret_key, ENV['SECRET_KEY']
Stripe.api_key = settings.secret_key
....
get '/' do
erb :index
end
post '/charge' do
# Amount in cents
#amount = 500
customer = Stripe::Customer.create(
:email => 'customer#example.com',
:card => params[:stripeToken]
)
charge = Stripe::Charge.create(
:amount => #amount,
:description => 'Sinatra Charge',
:currency => 'usd',
:customer => customer.id
)
erb :charge
end
So in this instance, they set the API Key to be the application's secret key. They don't pass any Access Token in the request either. So I'm a bit confused why an Access Token would be set as a secret API Key in the previous doc or why I should pass it with each request, when all their example docs don't even do that.
To understand this, you should know first that the Stripe API can be used to build applications that serve two kinds of audiences:
to accept payments from end-users as a merchant (normal use-case) and
to provide add-on services to merchants having their own Stripe
accounts (eg. one service helps me configure the emails to be sent out on different Stripe events)
Hence, all the API endpoints can be authorized in two ways:
the API key way which you can directly get from your Account Settings. This identifies your Stripe account
the access token way through Stripe Connect. This identifies the Stripe account of the connected merchant.
What the Stripe Connect docs is telling you is that suppose you are building an application that serves use-case #2 above, then you must remember to authorize each of your API calls with the right access token and not have a global API key (which, by the way, is fully acceptable for use case #1) as you might be making changes incorrectly to the wrong account(s).
So, if use case #1 is what you want to do, you don't have to worry about Stripe Connect at all.
I already have the login (OAuth) piece working with my app, what I am trying to do now is pull down the authenticated users' activity list (status feed, for example).
The user has the option to pull this list down after the fact of them being authenticated and here is my code, thus far:
# User Model
def gplus
auth = authorizations.find_by_provider("gplus")
client = Google::APIClient.new(application_name: "AppName", application_version: '1.0', authorization: nil)
plus = client.discovered_api('plus', 'v1')
result = client.execute(
key: API["gplus"][Rails.env]["secret"],
api_method: plus.people.get,
parameters: { 'collection' => 'public', 'userId' => 'me' }
)
return result.data
end
Here is the problem I keep running into (from rails console)
#<Google::APIClient::Schema::Plus::V1::Person:0x3fe649ed04bc
DATA:{"error"=>{"errors"=>[{"domain"=>"usageLimits", "reason"=>"keyInvalid", "message"=>"Bad Request"}], "code"=>400, "message"=>"Bad Request"}}>
I am using the https://github.com/google/google-api-ruby-client... any reason why this won't work?
Code is close, but not quite there!
You're getting the auth object, but not actually passing it to your client there (you're setting it to nil).
You seem to be passing your client secret as the API key, which will cause problems. They API key is for a "simple API access" key from the API console - you don't need to pass anything if you're using an oAuth 2.0 token. If you'd like, you can pass a Server simple API key. This actually catches incorrectly using access tokens for a different project, so can be handy, but isn't required.
You don't need to specify a collection argument for plus.people.get
Additionally, make sure that the Google+ API is enabled under Services in the API console: http://developers.google.com/+
I can authenticate and fetch an access_token and the corresponding refresh_token fine (subsequent API interactions are also fine).
However, I seem to only be able to refresh a token (POST to /oauth/token with grant_type=refresh_token) before the access_token actually expires. After the expiration, the same refresh code (exactly that provided within the docs), returns with an error of invalid_grant.
I am using the soundcloud-ruby SDK, FWIW, but I can reproduce it through curl.
As an aside, I found some old messages from the Google Group mentioning that I can request a non-expiring token, but I do not see this mentioned anywhere in the docs. Is this still a viable option?
That is correct. Refresh tokens cannot be used after an access token expires.
You can request a non-expiring access token by specifying scope=non-expiring when constructing an authorization URL. To do this with the Ruby SDK, simply pass the additional params to the authorize_url method:
require 'soundcloud'
client = Soundcloud.new(
:client_id => 'YOUR_CLIENT_ID',
:client_secret => 'YOUR_CLIENT_SECRET',
:redirect_uri => 'REDIRECT_URI'
)
client.authorize_url(:scope => 'non-expiring')
The rest of the flow should be exactly the same (grab the 'code' parameter from the query string and make a POST request to /oauth2/token).
I'm at the point of involuntary hair loss while trying to refresh the Yahoo OAuth access token in Ruby.
Using the OmniAuth and OAuth gems, I'm able to get an access token from Yahoo, however it expires in one hour.
I'm following the Yahoo instructions to refresh an expired token, and am consistently returned a 401.
If someone could show me how to refresh the access token using the OAuth gem, I'd be greatly appreciative.
First, make sure you are saving your oauth_session_handle parameter from your original get_access_token call.
Then, when you are looking to refresh the access_token do something like this:
request_token = OAuth::RequestToken.new(consumer,
config["ACCESS_TOKEN"],
config["ACCESS_TOKEN_SECRET"])
token = OAuth::Token.new(config["ACCESS_TOKEN"],
config["ACCESS_TOKEN_SECRET"])
#access_token = request_token.get_access_token(
:oauth_session_handle => config["SESSION_HANDLE"],
:token => token)
... where ...
config["ACCESS_TOKEN"] is your old access token
config["ACCESS_TOKEN_SECRET"] is your old secret
config["SESSION_HANDLE"] is your oauth_session_handle
consumer is your OAuth::Consumer.new reference
I store the config variable in a yaml file and then load it on startup.
Remember to store the #access_token for next time.
I adapted this from an answer at YDN OAuth Forum.
Note: oauth_session_handle is returned as a param by the call to get_access_token:
access_token = request_token.get_access_token(:oauth_verifier => oauth_verifier)
oauth_session_handle = access_token.params['oauth_session_handle']
This was less than obvious from looking at the oauth-ruby/oauth code