【问题标题】:Google Classroom API 401 Error谷歌课堂 API 401 错误
【发布时间】:2016-09-22 03:50:47
【问题描述】:

我正在尝试使用 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"
}

如果有任何帮助,我将不胜感激。 道格

附:我得到了这段代码的安全含义。它位于仅用于实验的安全环境中。它不会看到曙光。

【问题讨论】:

    标签: javascript google-api oauth2 service-accounts google-classroom


    【解决方案1】:

    根据同样收到 401 错误的 forum,尝试撤销旧的 oauth。正如related thread 中所述,您遇到的 401 Unauthorized 错误可能与使用 OAuth 2.0 client IDOAuth 2.0 Authorization 有关。

    Suggested action: 使用长期刷新令牌刷新访问令牌。如果失败,请直接通过 OAuth 流程。

    【讨论】:

      猜你喜欢
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多