问题
I need to use a google projects service account to access google API using JavaScript. In order to do this I need to OAuth2 to google API servers to get an auth token.
I understand that Google provides a library (GAPI) for use on node servers, but I need a solution that will work in other secure JavaScript environments.
回答1:
There are two major divisions to this task.
- Configuring
- Coding
First the Configuration steps.
- If you don't have a google account:
- Navigate to google.com
- Find and Click "Sign In"
- Click "More Options"
- Click "Create Account"
- Follow the steps to create an account
- Navigate to the api dashboard: console.developers.google.com/apis/dashboard
Select or create a project by clicking on the current project. The project I have showing is called "My Project"
Click and enable those API you plan to work with
- navigate to the credentials section: console.developers.google.com/apis/credentials
- Click and select "Service account key"
- If you create a new service account, for testing set the role to "project" "owner". You'll want to read up on google Api roles eventually. See Managing Roles and Granting Roles to Service Accounts
- Ensure "Key Type" is "Json" and click "Create". You're key/cert will automatically download
Now for the Coding portion.
- First download jsrsasign and add reference to "jsrsasign-all-min.js". If you want you can download just "jsrsasign-all-min.js" from github
Second update the following script with your cert/key (downloaded earlier):
function postJWT(jwt, callback) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function () { if (this.readyState == 4) { if (this.status == 200 && callback) { callback(this.responseText); return; } if (console) console.log(this.responseText); } }; var parameters = "grant_type=" + encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer") + "&assertion=" + encodeURIComponent(jwt); xhttp.open("POST", "https://www.googleapis.com/oauth2/v4/token", true); xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhttp.send(parameters); } function getCert() { var cert = //your json key (downloaded earlier) goes here { "type": "service_account", "project_id": "proj..", "private_key_id": "e18..", "private_key": "-----BEGIN PRIVATE KEY-----\nMII..==\n-----END PRIVATE KEY-----\n", "client_email": "service-account@...iam.gserviceaccount.com", "client_id": "5761..", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://accounts.google.com/o/oauth2/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..service-account%40...iam.gserviceaccount.com" }; return cert; } function getJWT() { var cert = getCert(); var key = KEYUTIL.getKey(cert.private_key); var headers = { "alg": "RS256", "typ": "JWT" }; var issued = Math.floor(new Date().getTime()/1000); var claims = { "iss": cert.client_email, "scope": "https://www.googleapis.com/auth/analytics.readonly", "aud": "https://www.googleapis.com/oauth2/v4/token", "exp": issued + 3600, "iat": issued }; var jwt = KJUR.jws.JWS.sign(headers.alg, headers, JSON.stringify(claims), key); return jwt; }
When you test your code you should receive a json object back with an auth token. You can test your implementation like so:
postJWT(getJWT(text), function(){ let token = JSON.parse(response).access_token; //Do your api calls here using the token. //Reuse the token for up to 1 hour. });
Here is an example successful json object with token:
{
"access_token": "ya29.c.ElkABZznrLNLK6ZAq2ybiH5lsRJpABE8p7MlZZJ0WCKcDNDv75lh-o1iRX__uMNUKSySiawm4YJGsbfqJH2JH61nRK6O2m0GJR7DgkEmo6ZlKtrvzke9C3xpwA",
"token_type": "Bearer",
"expires_in": 3600
}
Please note that this approach requires that the key/cert be accessible from your javascript environment. If this environment is public your api is vulnerable.
来源:https://stackoverflow.com/questions/47230956/how-can-i-retrieve-a-service-account-oauth2-token-from-google-api-with-javascrip