I want to get a access_token to get information from Google Analytics API by passing it in the browser . I am not able to find the correct documentation anywhere. I have tried multiple ways but nothing seems to work. As of now, I got tokens via Google Analytics Query Explorer and it works for 60 minutes. I am looking for a permanent token or a token which is valid for a more period of time.
In order to access private Google analytics data you need to be authorized. In order to be authorized you use something called Oauth2
The initial request will look something like this. It will allow the user to consent to your applications access to their data
GET https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
Once the user has consented to your accessing their data, you will be given an authorization code.
Once you have the authorization code you can exchange it for an access token. This is a http post request.
POST https://accounts.google.com/o/oauth2/token
code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code
The response should then look something like this.
{
"access_token" : "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}
The access token will work for one hour.
I recommend looking for a sample and a client library in your chosen programming language so that you dont have to do all this manually most of the libraries are designed to handle authentication and authorization for you.
Related
I am trying to use GA4 API (with Google Python Client & Google Analytics Data Python Client) of Google with the Credentials authentication:
credentials = Credentials(
token=config['access_token'],
refresh_token=config['refresh_token'],
client_id=config['client_id'],
client_secret=config['client_secret'],
token_uri="https://accounts.google.com/o/oauth2/token",
scopes=['https://www.googleapis.com/auth/analytics.readonly']
)
This is working when my access token is not expired. However, this access token is expiring after 1 hour and I want to refresh it via following method:
credentials.refresh(google.auth.transport.requests.Request())
However, this code is returning "invalid_grant" error.
For that problem, I checked almost everything suggested (i.e. system clock/ntp, user permissions, etc.) however I couldn't fix the problem.
Also, I can't figure out about the refresh_token that I use is valid for Google Analytics 4 or not.
So, the questions are:
How can I able to solve this problem?
How can I assure that the refresh_token is valid for GA4?
If not valid, how can I refresh the refresh_token?
Is there any suggestion on the refresh of access_token, any other method or anything else?
Thanks
In my case, the solution was creating new OAuth client and generate a refresh_token for that account depend on the Google Analytics scope.
For that purpose, after I create the new client, I downloaded the client_secrets.json and run the Complete Example by Google and finally I am able to refresh the token.
I'm using directus to grant users access to ressources required by an SPA written in Angular. To authenticate users I created an auth service and interceptor to handle sessions and attach the "Authorization" header. Those services work fine and login as intended. But here comes the problem:
Directus session times are configured with default values (15 min validity for access_token, 7d for refresh_token) but as soon as the access_token expires I cannot retrieve a new one using the refresh token. This bugs me, because the goal is to keep users logged in for the next 7d (refresh_token lifespan) or until logout if they check this option.
My attempts at achieving this:
Since i'm using graphQL, i tried the "auth_refresh" mutation from the authentication documentation. While the access token is still valid, refreshing works fine. After the access token expired there is no way to retrieve a new one via a valid refresh token.
Alternatively I tried to achieve a refresh via the POST request specified by the docs (to double check if it was some sort of config error with graphql) but I encounter exactly the same problems as with graphQL. Directus returns either "401 unauthorized : Token expired."
if i extend the lifespan of the access token for longer than the server defined lifetime,
Response: Sending a token with prolonged life
or "401 unauthorized : Invalid user credentials." if I request a new token without an
"Authorization" header.
Response: Sending no access token
The refresh token is correctly loaded and sent to the server as specified in the docs in both
cases.
Now my questions are:
Am I missing something? I haven't found any further specification in the docs and the Auth0 protocol specifies that a new access token should be retrievable with a valid refresh token.
If this feature is not intended: How could I achieve a "keep me signed in" option with directus? I would like to keep user rights management in one place and do not really want to handle user auth redundantly for my current use case.
2b. Why is the lifespan of the refresh token so much longer than the lifespan of the access token if this isn't intended?
One of my thoughts is, that it has to do with access rights of the "public" role on the "directus_sessions" table. But I can't think of a way to grant only read rights for owned/received tokens, since there are no payload variables available inside the filters. Could this be the cause? Would there be a way to achieve this?
Thx&Greetz
There is an app that wants to authenticate with my users using oAuth2.
So they open a window, with the authorize URL, and parameters (such as redirect uri)
Like: https://my-website.com/api/authLauncherauthorize?redirect=SOME_URI
Now I have my own firebase-login, and when the user logs in, I get their access token from firebase. Which is what I want to respond with.
However, in oAuth2 guides/explanations like https://aaronparecki.com/oauth-2-simplified/ I see I am supposed to return an authorization code, and I don't understand where can I get that from?
What I can do, is generate a bullshit code, pair it in the DB to the access token, and then in the "token" request, send the correct access token. Is that what I am supposed to do?
Just to be clear, this is my first time writing an oAuth2 service myself.
OAuth is a system that provides authenticated access to resources. This resource can be for example a user page or editing rights to that user page. So your goal is to provide access to permissions to the right people.
When someone logs in, they get a token. Your part is to generate that token however you want, may it be some form of userdata into base64 or completely random. Take this token and link it against permissions, like viewing a page, editing it or even simpler things like viewing the email of a user.
OAuth2 tokens and/or permissions should be revokable without deleting a user. You should not use OAuth2 to identify someone.
If I am understanding your question correctly:
User visits some website
User wants to register or login using your websites OAuth2
You redirect back to the original page and send your generated token
The page can access content on your site with this token
Assuming you are the Host Site, given a User who wants to connect a 3rd party application, then the flow would be like this:
User lands on site - Clicks Login with Github
User is redirected to Github site where they login and click "Authorize"
Github redirects user back to your site /authorize with an auth token.
Your site then passes that token back to the 3rd party API (github in this case) in exchange for an access token and refresh token.
You can then pass that Authorization token to an API endpoint to get details about it. If the token expires, you can use the refresh token to get a new Auth token. Both Tokens should be stored in your database for your user.
However writing that all out I realize you are asking how do you generate the Authorization token, so I'm guessing you're actually the 3rd party API in this example. So you would want to generate an Authorization token using a random generator. Since you are using firebase, you'll probably wanna try out their token generator: https://github.com/firebase/firebase-token-generator-node
There's also some more up-to-date info here I believe: https://firebase.google.com/docs/auth/admin/#create_a_custom_token
And like you said, you would store that in a database associated with the user, and then when the Host Site sends that user's auth token to your server, you exchange it for the Authorization token (and refresh token if requested).
It's also worth reading through how google does it, because you'd be doing something similar: https://developers.google.com/identity/protocols/OAuth2UserAgent#validatetoken
JWT is another option of generating tokens: https://jwt.io/
Currently I have both Facebook and LinkedIn Oauth2 flow working fine. Because in some cases I don't want the user to redirect to another page, I use the Facebook JS SDK that works fine, retrieving the access token and sending it to the server where I retrieve user data with REST calls.
Unfortunately, I'm not having success in doing the same with the LinkedIn JS SDK. The official documentation isn't helpful at all in that regard: https://developer.linkedin.com/docs/getting-started-js-sdk.
I retrieve user data in the server because it's easy to forge fake data in the client side and send it to the server, so a client side solution for that is not an option.
If I try to use the token that I get in js in the REST API I get Invalid access token. (401)
There are several opened questions that doesn't have any response (or a helpful response) here in SO:
2015-08-03 - No response:
Javascript: Linkedin Access TOken
2016-05-29 - No response:
can I get access token through LinknedIn JS SDK?
2016-08-31 - No helpful response (data is retrieved in the front-end):
How to Get Access Token Using LinkedIn API JavaScript SDK
2017-06-30 - No helpful response:
LinkedIn OAuth token with Javascript SDK
In the below question, there is a comment that says what I'm already guessing:
[...] Honestly I think the JS API is completely useless like this
because if you can't verify/use the token server-side you basically
cannot trust any of the information.
2015-07-22 - No helpful response (data is retrieved in the front-end):
get linkedin Access Token with JavaScript SDK
There's some information about exchanging the Javascript API tokens with a REST API OAuth token, but in the references I've found the links are broken (and it would be impractical to do this, depending on the complexity, instead of using the token directly, like in the Facebook JS SDK):
http://developer.linkedin.com/documents/exchange-jsapi-tokens-rest-api-oauth-tokens
https://developer-programs.linkedin.com/documents/exchange-jsapi-tokens-rest-api-oauth-tokens
So, I would like to know if there is some way to login with LinkedIn using the JS SDK and retrieve the user data in the back-end using REST calls (like I do in the Oauth2 flow), hopefully with official docs.
I've had the same problem and the only way I found to use the JS token was to add the header oauth_token instead of an Authorization Bearer header:
POST https://api.linkedin.com/v1/people/~:(id,firstName,lastName,picture-url,email-address)?format=json
Headers {
'oauth_token': JS_TOKEN
}
The JS_TOKEN I'm reading on frontend from IN.ENV.auth.oauth_token.
I've been struggling with the same issue for some time, this is the way I solved it (not using the JS SDK):
Step 1: you send your user to the LinkedIn login page, in the redirect_uri param use an endpoint to handle all the logic related to LinkedIn.
Step 2: When the user finishes login in, Linkedin is going to send a GET request to that endpoint, this request will have an "Authorization Token", this token is just a temporal token and it won't allow you to get your user's data.
Step 3: Use the Authorization Token you just received and send a post request to Linkedin
Step 4: Linkedin will send you back an Access Token (this is the one you are looking for), now you can request all the information you want
Step 5: Redirect your user back to your web app.
The structure of the request as well of the anchor tag params are available here: https://developer.linkedin.com/docs/oauth2
As per the querybuilder
My API URI looks:
https://www.googleapis.com/analytics/v3/data/ga?ids=ga:12134345&
start-date=30daysAgo
&end-date=yesterday&
metrics=ga:pageviews,ga:pageValue,ga:entrances&
dimensions=ga:pagePath,ga:daysSinceLastSession,ga:sessionCount,ga%3
Abrowser,ga:city&filters=ga:pagePath==/home
But when i execute in my domain, it throws error as login
required. So for that i also passed API-KEY as &key="****" to the
above url. But still no success. Still i get the same error
Am i missing something? Can i embed this results to embed-api in charts
The api key is different from the access token. If you use the Query Explorer you can check a box in the report to include the access token in the query URI, which will allow you to just paste it into your browser's address bar (note: access tokens expire after an hour).
If you want to learn how to get an access token programmatically, you should check out the OAuth 2.0 section of the Google Developers site:
https://developers.google.com/identity/protocols/OAuth2