From article: https://github.com/gimite/google-drive-ruby/blob/master/doc/authorization.md
Code:
credentials = ... same as above ...
credentials.code = authorization_code
credentials.fetch_access_token!
Then
If you want to restore a session afterwards, you can store credentials.refresh_token after credentials.fetch_access_token!
But after credentials.fetch_access_token!
credentials.refresh_token is nil
How i can get refresh_token?
Or save credentials to database for next time?
Need add additional_parameters:
require "googleauth"
credentials = Google::Auth::UserRefreshCredentials.new(
client_id: "YOUR CLIENT ID",
client_secret: "YOUR CLIENT SECRET",
scope: [
"https://www.googleapis.com/auth/drive",
"https://spreadsheets.google.com/feeds/",
],
redirect_uri: "http://example.com/redirect",
:additional_parameters => {
"access_type"=>"offline",
"include_granted_scopes"=>"true",
"prompt" => "consent"
}
)
auth_url = credentials.authorization_uri
credentials.code = authorization_code
credentials.fetch_access_token!
then get:
refresh_token = credentials.refresh_token
and then refresh_token can be stored in database and used later:
credentials.refresh_token = refresh_token
credentials.fetch_access_token!
session = GoogleDrive::Session.from_credentials(credentials)
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'm getting this error
The request signature we calculated does not match the signature you provided
The Canonical String for this request should have been
The String-to-Sign should have been
I am trying to implement the SP APIs in rails.
I've fetched the access-token from https://api.amazon.com/auth/o2/token endpoint.
And after wards created the temporary session token using Aws::STS::Client.
I used Aws::Sigv4::Signer for signature.
First Step (Access Token)
payload = {
grant_type: 'refresh_token',
client_id: [ClientId],
refresh_token: [RefreshToken],
client_secret: [ClientSecret],
}
headers = {'Content-Type': 'application/json'}
response = HTTParty.post("https://api.amazon.com/auth/o2/token", body: payload.to_json, headers: headers)
access_token = response["access_token"]
Second Step (Create Assume Role Using AWS::STS)
result = sts = Aws::STS::Client.new(
region: "us-east-1",
credentials: Aws::Credentials.new("aws-access-key", "aws-secret-key")
).assume_role({
role_arn: "role_arn",
role_session_name: 'sp-api'
})
enter code here
Third Step (Create Signature )
signer = Aws::Sigv4::Signer.new(
service: 'execute-api',
region: 'us-east-1',
# static credentials
access_key_id: access_key_id,
secret_access_key: secret_access_key,
session_token: session_token
)
signature = signer.sign_request(
http_method: 'GET',
url: 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID',
headers: {
'host' => 'sellingpartnerapi-na.amazon.com',
'X-Amz-Access-Token' => access_token,
})
Final Step (To call the API with the Signature Headers)
headers = {
'Content-Type' => 'application/json',
"host" => signature.headers["host"],
"X-Amz-Date" => signature.headers['x-amz-date'],
"X-Amz-Security-Token" => signature.headers["x-amz-security-token"],
"X-Amz-Content-Sha256" => signature.headers["x-amz-content-sha256"],
"Authorization" => signature.headers['authorization']
}
data = HTTParty.send(:get, "https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID", headers: headers)
I use OAuth2::Client for get access_token.
Need refresh it with refresh_token
client_id = '95585XXXXXXXoogleercontent.com'
secret_key = 'R10Ze490IYa'
client = OAuth2::Client.new(client_id, secret_key, {
authorize_url: 'https://accounts.google.com/o/oauth2/auth',
token_url: 'https://accounts.google.com/o/oauth2/token'
})
redirect_url = client.auth_code.authorize_url({
scope: 'https://www.googleapis.com/auth/analytics.readonly',
redirect_uri: 'https://example.com',
access_type: 'offline'
})
auth_code = '4/5AF6VI0JMcmA38XXXXX' # getted from redirect_url clicking
access_token = client.auth_code.get_token(auth_code, redirect_uri: 'https://example.com')
Then I try to refresh token:
access_token.refresh!
And I have error:
RuntimeError: A refresh_token is not available
Need add - prompt: 'consent':
redirect_url = client.auth_code.authorize_url({
scope: 'https://www.googleapis.com/auth/analytics.readonly',
redirect_uri: 'https://example.com',
access_type: 'offline',
prompt: 'consent'
})
Then you can get new access_token:
new_access_token = access_token.refresh!
Also you can save token for future using:
hash = access_token.to_hash # save it
# load:
loaded_token = OAuth2::AccessToken.from_hash(client, hash)
I would like to set my token only once per user, do you know how to check if my token is already set ?
Here is my Controller :
def connexion
code = request.params[:code]
#decoded_code = URI.decode(code)
#id_connection = request.params[:id_connection]
#token = HTTParty.post('https://test-sandbox/auth/token/access',
body: {
client_id: XXXXXX,
client_secret: "YYYYYYYYYYYYYYYYY",
code: #decoded_code
}
)
end
If I go back to my page and re-set the token I have the following error : You have already got an access_token for this user
You can use ||= operator to set token, if it is not set than it will try to get token
#token ||= HTTParty.post('https://test-sandbox/auth/token/access',
body: {
client_id: XXXXXX,
client_secret: "YYYYYYYYYYYYYYYYY",
code: #decoded_code
}
)
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