Google auth for YouTube doesn't work in Rails - ruby-on-rails

I'm using Rails 5.1.1 an yt gem 0.28
I used official gem docs (link is above).
Also these docs Github
And tried to check myself with this tutorial on SitePoint
If you check comments below the SP's tutorial - there was the same issue but yt owner removed Issues so I can't use it.
Gem seems to be working fine. At least when I place:
video = Yt::Video.new id: 'BPNYv0vd78A'
in video_controllers.rb and then ask for video.description, it answers with description. So lets put a tick here.
And I cofigured YT as it was said:
Yt.configure do |config|
config.log_level = :debug
config.client_id = "[my_client_id].apps.googleusercontent.com"
config.client_secret = "[my_secret_key]"
config.api_key = '[my_api_key]'
end
I copied values from google_oauth2, so if there it's OK, it must be OK here as well.
But when I try to use anything involving authentification something very strange happens.
FIRST PART - access token
According to the manual, if I have access token I can just:
account = Yt::Account.new access_token: 'ya29.[authenticating_user_token]'
account.email
Here goes the message:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
Also it offers curl command to simulate this action:
curl -X GET -H "content-length: 0" -H "user-agent: Yt::Request (gzip)" -H "authorization: Bearer ya29.[authenticating_user_token]" -H "host: www.googleapis.com" "https://www.googleapis.com/oauth2/v2/userinfo?key=[my_api_key]"
authenticating_user_token is the same as I get from google auth json like user.auth_hash["credentials"]["token"]
my_api_key is the same key from Google Developers Console.
When I requested account's value through byebug, it gave me:
#<Yt::Models::Account:0x000000051473f0 #access_token="ya29.[authenticating_user_token]", #refresh_token=nil, #device_code=nil, #expires_at=nil, #authorization_code=nil, #redirect_uri=nil, #force=nil, #scopes=nil, #authentication=nil>
The first question that stays without answer: "Why it uses api key if docs say all I need is access_token?"
SECOND PART refresh_token
Actually, after the fiasco with access token I thought that it might be that
"credentials"=>{"token"=>"ya29.[authenticating_user_token]",
"expires"=>true,
"expires_at"=>1518443279}
is the mysterious refresh token!
It gave me the same 'Invalid Credentials'
So I modified videos_controller.rb:
account = Yt::Account.new(refresh_token: user.auth_hash["credentials"]["token"],
expires_at: user.auth_hash["credentials"]["expires_at"],
expires: user.auth_hash["credentials"]["expires"])
This time with byebug I got account's value:
#<Yt::Models::Account:0x00000007a6e5a8 #access_token=nil, #refresh_token="ya29.[you know_what]", #device_code=nil, #expires_at=1518443279, #authorization_code=nil, #redirect_uri=nil, #force=nil, #scopes=nil, #authentication=nil, #user_infos=#<Yt::Collections::UserInfos:0x00000007a305a0 #parent=#<Yt::Models::Account:0x00000007a6e5a8 ...>, #auth=#<Yt::Models::Account:0x00000007a6e5a8 ...>, #page_token=nil, #last_index=0, #items=[]>, #refreshed_authentications=#<Yt::Collections::Authentications:0x007ff0080054b0 #parent=#<Yt::Models::Account:0x00000007a6e5a8 ...>, #auth=#<Yt::Models::Account:0x00000007a6e5a8 ...>, #auth_params={:client_id=>"[my_client_id].apps.googleusercontent.com", :client_secret=>"[my_client_secret]", :refresh_token=>"[you_know_what]", :grant_type=>:refresh_token}, #page_token=nil, #last_index=1, #items=[], #where_params={}>>
And requesting account.email:
*** Yt::Errors::Unauthorized Exception: A request to YouTube API was sent without a valid authentication:
{}
You can retry the same request manually by running:
nil
And the second question: "Was it refresh token or not?"
In YouTube account I have a working channel so it couldn't be a reason.
I would appreciate any help! If you have any app working with YouTube, please share the link to Github, so I could figure out what's wrong with my app!

Well, that's embarssing - nobody even tried to help...
Still I found the source of errors.
So the token from auth["credentials"]["token"] is access token.
My problems came because I didn't specify :scope in config/initializers/device.rb
It should be:
config.omniauth :google_oauth2, "[client_id_from_google_developers_console].apps.googleusercontent.com", "[key_from_google_developers_console]", scope: 'userinfo.profile, userinfo.email, youtube'
Also I noticed the error comes when a token expires, so you should do something like begin-rescue thing to update user's token time-to-time.

btn-group
use this class for the button div like <div class="btn-group"></div>
and apply
btn-group button:hover {
background-color: #3e8e41;
}
.btn-group:after {
content: "";
clear: both;
display: table;
}
.btn-group button:not(:last-child) {
border-right: none;
}

Related

Twitter API Oauth2 issue getting Access Token

Following this guide: https://developer.twitter.com/en/docs/authentication/oauth-2-0/user-access-token. I am getting this error when making the POST oauth2/token at the step 3 request:
`
{
"errors": [
{
"code": 99,
"message": "Unable to verify your credentials",
"label": "authenticity_token_error"
}
]
}
`
This is my request: (Note that I hide the client_id and code). The code is the one I receive after the step 2, doing the GET oauth2/authorize callback. Header: Content-Type - application/x-www-form-urlencoded;charset=UTF-8
My Request
I found the issue, the problem was that in the Bot Application, editing the Auth settings of my twitter app, I had the option: Confidential client which needed a Basic Auth = authorization: Basic ${'username + password encoded here'}

Create organizationalBrandingProperties

I'm trying to create Organizational branding via Graph API
Unfortunately it doesn't work as documented
curl --fail-with-body --silent --show-error --oauth2-bearer TOKEN -X PUT -H 'Content-Type: application/json' -d #- https://graph.microsoft.com/v1.0/organization/7c9674e7-ad41-482b-af13-fff7ba1c38f6/branding <<< '{
"backgroundColor":"#FFFF33",
"signInPageText":"Welcome",
"usernameHintText":"hint"
}'
{
'error': {
'code': 'Request_BadRequest',
'message': 'Specified HTTP method is not allowed for the request target.',
'innerError': {
'date': '2021-04-21T12:59:57',
'request-id': 'a5ce577c-d0a9-4888-9999-521d7ba452b1',
'client-request-id': 'a5ce577c-d0a9-4888-9999-521d7ba452b1'
}
}
neither PATCH works:
curl --fail-with-body --silent --show-error --oauth2-bearer TOKEN -X PATCH -H 'Content-Type: application/json' -d #- https://graph.microsoft.com/v1.0/organization/7c9674e7-ad41-482b-af13-fff7ba1c38f6/branding <<< '{
"backgroundColor":"#FFFF33",
"signInPageText":"Welcome",
"usernameHintText":"hint"
}'
{
"error": {
"code": "Request_ResourceNotFound",
"message": "Resource '7c9674e7-ad41-482b-af13-fff7ba1c38f6' does not exist or one of its queried reference-property objects are not present.",
"innerError": {
"date": "2021-04-21T13:07:43",
"request-id": "c2c7056b-0043-40cb-82b8-6d262f190005",
"client-request-id": "c2c7056b-0043-40cb-82b8-6d262f190005"
}
}
I tried opening an Azure support request but they told me
The AAD Developer queue is experiencing a very high number of requests.
Please expect a delay in the assignation as the cases are assigned considering case severity, time in queue, customer service level and business impact.
Since Azure support has proven to be useless yet again, maybe somebody here would be able to help me? :)
Based on my test, I have the same error when I use PUT method.
But PATCH works fine for me.
id should be the organization id or tenant id.
Please get the id first with
GET https://graph.microsoft.com/beta/organization/
Then use the id for PATCH method:
PATCH https://graph.microsoft.com/v1.0/organization/{id}/branding
Content-Type: application/json
Content-Language: en-US
{
"backgroundColor": "#FFFF33",
"signInPageText": "Welcome",
"usernameHintText": "hint"
}
Update:
Application token is not supported for this endpoint. See Permissions.
Microsoft support finally responded (after 2 months!) with
Application Permission are currently not supported on this
endpoint, meaning that you will need an on-behalf of user token with
Delegated permissions to use this endpoint.
Since your goal was to automate this process, one workaround that
sometimes is feasible is to have a dedicated user in your tenant to
perform those actions, and that will authenticate with ROPC flow. This
flow allows to directly send the credentials information (username and
password) and because of that does not require an UI or interaction.
There is currently a known issue regarding the GET and PATCH method for the branding endpoint that is already reported and the fix
is in progress. This issue will cause an 404 error mentioning that the
tenant resource is not found.
Issue seems to be with locale being used, If you wish to get/update
the default branding, can you please try to include an header with
Accept-language as 0 (shown in the below image), if you want to get
branding for any other locale, you’ll need to pass the valid ISO-639
locale.

Google blogger api and expired secret key.

I have already managed to add some posts to my blog using google api and oauth and ran into some problems. I have tried for days - or weeks - to find the best question to ask and I believe I have isolated the problem. Apparently the secret key only works only for one hour. but after an hour at this line:
$service->blogs->getByUrl("theurlofmyblog.blogspot.com");
I get this error:
Google_Service_Exception in REST.php line 118:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
Some of the experts on forums have suggested that one must go to this address https://developers.google.com/oauthplayground/ and get a referesh token. But nobody has mentioned that how should we use that token. Do I put it inside the json file? There must be something like this - don't laugh please, this is supposed to be a suedo code -:
if(the key is expired)
use my referesh key and get me another key
Any experience?
As described in Google’s OAuth 2.0 documentation, you should receive a refresh token during the authentication flow. You should store that token someplace, then use it to get a new access token when necessary.
The exact procedure to exchange a refresh token for a new access token will depend on what OAuth client library you are using. In Signet (Google’s OAuth library for Ruby), for example, it’s done as part of fetch_access_token.

Getting list of users in Google Admin SDK

I have OAuth login in my app. After that I have access_token.
I check token in google token info service:
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<access_token>
And It returns:
{
"issued_to": "554651647288-tquejcu6mctplq4kin5dd9r81mtkg3vv.apps.googleusercontent.com",
"audience": "554651647288-tquejcu6mctplq4kin5dd9r81mtkg3vv.apps.googleusercontent.com",
"scope": "https://www.googleapis.com/auth/admin.directory.group https://www.googleapis.com/auth/admin.directory.orgunit https://www.googleapis.com/auth/admin.directory.user",
"expires_in": 3299,
"access_type": "online"
}
As you can see I have admin user directory permission.
Then I send GET request for getting information about user
curl -X GET https://www.googleapis.com/admin/directory/v1/users/test_user#test.com?access_token=<access_token>
And google returned me right user information. After that I decided to get list of users.
curl -X GET https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&access_token=<access_token>
And google returned me:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
But I don't understand why google returned me so error.
Could you please help me with this problem?
Thanks.
There are two solutions here.
1.This is the simple one. Put the URL params in quotes. This should do the trick - (fake access token used)
curl "https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&access_token=asdf.AHEasdfyIc9vuPQ_BGONpzEJkasdfWYXGujPw5iPI"
You don't need to pass in -X GET as that is the default.
2.In general it is bad practice to send the access_token in the URL as this URL may get logged somewhere along the way for innocuous reasons. You can also do this through HTTP Header of Authorization -
curl -H "Authorization: Bearer asdf.AHEasdfyIc9vuPQ_BGONpzEJkasdfWYXGujPw5iPI" https://www.googleapis.com/admin/directory/v1/users?customer=my_customer

{ "error": { "message": "Missing client_id parameter.", "type": "OAuthException", "code": 101 } }

Im following Ryan Bates Screen Cast #360 Facebook Authentication...
When i get to to part where i click the link to log into facebook i get a
{
"error": {
"message": "Missing client_id parameter.",
"type": "OAuthException",
"code": 101
}
}
i tried restarting the server like previously stated
Im pulling my hair out trying to figure this out
My site url at facebook development page is correct i've followed his steps hundreds of times
May be you have not setup the env for FACEBOOK_KEY and FACEBOOK_SECRET
In terminal (if you are using linux or mac)
$ export FACEBOOK_KEY=zzyzyzyzyzyzzy
$ export FACEBOOK_SECRET=zzyzyzyzyzyzzysbdbdsndnds
#now start rails from same terminal
$ rails s
this will now pass the values of FACEBOOK_KEY and FACEBOOK_SECRET to application.
Or second option
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET']
to this
provider :facebook, 'FACEBOOK_KEY', 'FACEBOOK_SECRET'
Diff between using two approaches.
The drawback of second type is, you need to keep the keys into the code repository. which is not a safe approach.

Resources