Google uses AI technology to translate content into your preferred language. AI translations can contain errors.
Chrome Device Token API 示例
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Python
import jwt
import json
import requests
import sys
import time
import codecs
SERVICE_ACCOUNT_FILE = './service_account_key.json'
JWT_AUDIENCE = 'https://oauth2.googleapis.com/token'
JWT_SCOPE = 'https://www.googleapis.com/auth/chromeosdevicetoken'
TOKEN_REQUEST_URL = 'https://oauth2.googleapis.com/token'
INVALIDATE_TOKEN_API_URL = 'https://chromedevicetoken.googleapis.com/v1/users:invalidateToken'
def get_access_token_for_user(service_account_email, private_key_id, private_key, user_email):
'''
See instructions for getting a signed JWT here
https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth
'''
iat = time.time()
exp = iat + 3600
payload = {'iss': service_account_email,
'sub': user_email,
'aud': JWT_AUDIENCE,
'scope': JWT_SCOPE,
'iat': iat,
'exp': exp
}
additional_headers = {'kid': private_key_id}
signed_jwt = jwt.encode(payload, private_key, headers=additional_headers,
algorithm='RS256')
grant_type = codecs.decode(
'urn:ietf:params:oauth:grant-type:jwt-bearer', 'unicode_escape')
payload = 'grant_type=' + str(grant_type) + '&assertion=' + signed_jwt
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.post(TOKEN_REQUEST_URL, data=payload, headers=headers)
print(f'Response HTTP status code: {response.status_code}')
print(json.dumps(response.json(), indent=2))
return response.json()['access_token']
def invalidate_token(user_email):
print(f'invalidate token for user {user_email}')
with open(SERVICE_ACCOUNT_FILE, 'r') as service_account_key_json_file:
service_account_key = json.load(service_account_key_json_file)
service_account_email = service_account_key['client_email']
private_key_id = service_account_key['private_key_id']
private_key = service_account_key['private_key']
print(f'using service account {service_account_email}')
print(f'using private key id {private_key_id}')
access_token = get_access_token_for_user(service_account_email, private_key_id,
private_key, user_email)
response = requests.post(
INVALIDATE_TOKEN_API_URL,
headers={
'Authorization': 'Bearer ' + access_token,
'Content-Type': 'application/json'
},
json={
'token_type': 'SAML_PASSWORD'
})
# Successful call should have HTTP status code 200 and an empty response body.
print(f'Response HTTP status code: {response.status_code}')
print(json.dumps(response.json(), indent=2))
if __name__ == '__main__':
invalidate_token(sys.argv[1])
C#
private async Task<string> InvalidatePasswordTokenForUser(string userAccessToken)
{
const string tokenRequestURI = "https://chromedevicetoken.googleapis.com/v1/users:invalidateToken";
var jsSerializer = new JavaScriptSerializer();
var body = new Dictionary<string, object>();
body["token_type"] = "SAML_PASSWORD";
string jsonString = jsSerializer.Serialize(body);
HttpWebRequest tokenRequest = (HttpWebRequest)WebRequest.Create(tokenRequestURI);
tokenRequest.Method = "POST";
tokenRequest.Headers.Add(string.Format("Authorization: Bearer {0}", userAccessToken));
tokenRequest.ContentType = "application/json";
tokenRequest.Accept = "Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
byte[] _byteVersion = Encoding.ASCII.GetBytes(jsonString);
tokenRequest.ContentLength = _byteVersion.Length;
Stream stream = tokenRequest.GetRequestStream();
await stream.WriteAsync(_byteVersion, 0, _byteVersion.Length);
stream.Close();
WebResponse tokenResponse = await tokenRequest.GetResponseAsync();
using (StreamReader reader = new StreamReader(tokenResponse.GetResponseStream()))
{
string responseText = await reader.ReadToEndAsync();
if (responseText != null && responseText.Length > 0)
{
return responseText;
}
throw new FormatException("Unexpected response format: " + responseText);
}
}
Appscript
function runInvalidateToken() {
var url = 'https://chromedevicetoken.googleapis.com/v1/users:invalidateToken';
var userToImpersonate = '...@....';
var service = getOAuth2Service(userToImpersonate, 'https://www.googleapis.com/auth/chromeosdevicetoken');
if (service.hasAccess()) {
var param = {
method: 'post',
contentType: 'application/json',
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
},
payload : JSON.stringify({
token_type : 'SAML_PASSWORD'
}),
muteHttpExceptions: true
};
var req = UrlFetchApp.getRequest(url, param);
Logger.log('Request : ');
Logger.log(req);
var response = UrlFetchApp.fetch(url, param);
Logger.log('ResponseCode : ' + response.getResponseCode());
Logger.log('ResponseBody : ' + response.getContentText());
} else {
Logger.log(service.getLastError());
}
}
/*
* This sample demonstrates how to configure the library for Google APIs, using
* domain-wide delegation (Service Account flow).
* https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
*/
// Private key and client email of the service account.
var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\n....\n-----END PRIVATE KEY-----\n';
var CLIENT_EMAIL = '....iam.gserviceaccount.com';
/**
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
getService().reset();
}
/**
* Configures the service.
*/
function getOAuth2Service(user, scopes) {
return OAuth2.createService('ChromeDeviceTokens:' + user)
// Set the endpoint URL.
.setTokenUrl('https://oauth2.googleapis.com/token')
// Set the private key and issuer.
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
// Set the name of the user to impersonate. This will only work for
// Google Apps for Work/EDU accounts whose admin has setup domain-wide
// delegation:
// https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
.setSubject(user)
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scope. This must match one of the scopes configured during the
// setup of domain-wide delegation.
.setScope(scopes);
}
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2026-05-13。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2026-05-13。"],[],[]]