0

我正在尝试使用 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我得到了这段代码的安全隐患。它位于仅用于实验的安全环境中。它不会看到曙光。

4

1 回答 1

0

根据这个同样收到 401 错误的论坛,尝试撤销旧的 oauth。如此相关线程中所述,您遇到的 401 Unauthorized 错误可能与使用OAuth 2.0 客户端 ID的OAuth 2.0 授权有关。

建议的操作:使用长期刷新令牌刷新访问令牌。如果失败,请直接通过 OAuth 流程。

于 2016-09-24T12:14:59.423 回答