我正在尝试使用 Google Classroom API 和服务帐户创建 Google Classroom 课程。我目前正在尝试使用 JavaScript,并且我已经完成了所有设置并正在努力获取课程列表。我设置了一个 JWT 并请求我收到的身份验证令牌。
{"access_token":"----ACCESS TOKEN HERE----------","token_type":"Bearer","expires_in":3600}
当我使用它来检索用户的课程列表(通过 GET)时没有问题。我收到了一个包含课程列表的正确回复,然后我将其显示在表格中。
当我尝试使用相同的过程尝试创建课程(通过 POST)时,我收到 401 错误:
{
"error": {
"code": 401,
"message": "The request does not have valid authentication credentials.",
"status": "UNAUTHENTICATED"
}
}
这是我用来验证的代码:
function authenticate(callback) {
function b64EncodeUnicode(str) {
str = JSON.stringify(str);
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
// constuct the JWT
var jwtHeader = {
"alg":"RS256",
"typ":"JWT"
}
jwtHeader = JSON.stringify(jwtHeader);
//construct the Claim
var jwtClaim = {
"iss":"psclassroomsync@psclassroomsync.iam.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/classroom.courses https://www.googleapis.com/auth/classroom.rosters",
"sub":"myemail@address.com", //this is an admin account I shouldn't really need this but tried with and without it
"aud":"https://www.googleapis.com/oauth2/v4/token",
"exp":(Math.round(new Date().getTime()/1000) + 60 * 10),
"iat":Math.round(new Date().getTime()/1000)
}
jwtClaim = JSON.stringify(jwtClaim);
//construct the signature
var key="-----BEGIN PRIVATE KEY-----Removed-----END PRIVATE KEY-----\n";
var jwtSign = b64EncodeUnicode(jwtSign);
var sJWT = KJUR.jws.JWS.sign("RS256", jwtHeader, jwtClaim, key);
var jwt = jwtHeader + "." + jwtClaim + "." + sJWT;
//request Token
var grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer";
var tokenRequest = "grant_type=" + grantType + "&assertion=" + sJWT;
var postURL = "https://www.googleapis.com/oauth2/v4/token"
request = $j.ajax({
url: postURL,
type: "post",
data: tokenRequest,
success: callback
});
}
这是我用来获取课程列表的代码。(这有效)
$j("#getClasses").click(function(event){
function getClasses(callback){
authenticate(function(data){
console.log(JSON.stringify(data));
var access_token = data["access_token"];
var apiUrl = 'https://classroom.googleapis.com/v1/courses'
var myData = 'teacherId=~(teacheremail)&access_token='+access_token;
var files = $j.ajax({
url: apiUrl,
type: "get",
data: myData,
success: function (data) {
var retreivedClasses = JSON.stringify(data);
for(var i = 0; i < data['courses'].length; i++){
nextObject = data['courses'];
$j('#classListTable').append('<tr><td>' + nextObject[i]['name'] + '</td><td>' + nextObject[i]['courseState'] + '</td><td>' + nextObject[i]['enrollmentCode'] + '</td></tr>');
}
//$j('#classList').text(retreivedClasses);
}
});
});
}
getClasses();
});
这是我用来通过 POST 创建课程的代码。我已经硬编码了一些变量进行测试,但仍然给出 401 错误。
$j("#createClass").click(function(event){
function createClass(callback){
authenticate(function(data){
console.log(JSON.stringify(data));
var access_token = data["access_token"];
var tokenInfo = $j.ajax({
url: 'https://www.googleapis.com/oauth2/v3/tokeninfo',
type: 'get',
data: "access_token="+access_token
});
var apiUrl = 'https://classroom.googleapis.com/v1/courses'
var myData = 'access_token='+access_token + '&ownerId=myemail@address.com&name=myClass'
console.log(myData);
var newGoogleClassroom = $j.ajax({
url: apiUrl,
type: "post",
data: myData,
success: function (data) {
var apiResponse = JSON.stringify(data);
$j('#classCreated').text(apiResponse);
}
});
});
};
createClass();
});
最后,这是我得到令牌信息时得到的。对我来说它看起来不错,即适当的范围:(但我是新手)
{
"azp": "removed",
"aud": "removed",
"scope": "https://www.googleapis.com/auth/classroom.courses https://www.googleapis.com/auth/classroom
.rosters",
"exp": "1474512198",
"expires_in": "3600",
"access_type": "offline"
}
我会很感激任何帮助。道格
PS我得到了这段代码的安全隐患。它位于仅用于实验的安全环境中。它不会看到曙光。