0

Google 클래스 룸 API 및 서비스 계정을 사용하여 Google 클래스 룸 과정을 만들려고합니다. 현재 JavaScript를 사용하여 실험하고 있으며 모든 것을 설정하고 물론 목록을 얻으려고 노력하고 있습니다. JWT를 설정하고받은 인증 토큰을 요청합니다.Google 클래스 룸 API 401 오류

{"access_token":"----ACCESS TOKEN HERE----------","token_type":"Bearer","expires_in":3600} 

사용자의 코스 목록 (GET을 통해)을 검색하는 데 사용하면 문제가 없습니다. 내가 테이블에 표시하는 코스 목록으로 적절한 응답을받습니다.

{ 
    "error": { 
    "code": 401, 
    "message": "The request does not have valid authentication credentials.", 
    "status": "UNAUTHENTICATED" 
    } 
} 

이 내가 인증을 사용하는 코드는 다음과 같습니다 : 나는 (POST를 통해) 과정을 만들려고하는 동일한 프로세스를 사용하려고하면

, 나는 401 오류가

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":"[email protected]", 
     "scope":"https://www.googleapis.com/auth/classroom.courses https://www.googleapis.com/auth/classroom.rosters", 
     "sub":"[email protected]", //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 + '&[email protected]&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" 
} 

어떤 도움을 주셔서 감사합니다. 더그

P. 나는이 코드의 보안 함의를 얻는다. 그것은 실험을위한 안전한 환경에 있습니다. 오늘의 빛을 보지 못할 것입니다.

답변

0

또한 forum에서 401 오류가 발생했기 때문에 오래된 oauth를 취소하십시오. 이 related thread에 명시된 바와 같이, 사용자가 경험 한 401 Unauthorized 오류는 OAuth 2.0 client ID을 사용하는 OAuth 2.0 Authorization과 관련이있을 수 있습니다.

Suggested action: 긴 수명의 새로 고침 토큰을 사용하여 액세스 토큰을 새로 고칩니다. 이것이 실패하면 OAuth 플로우를 통해 지시하십시오.