【问题标题】:Request had insufficient authentication scopes error when creating teacher through Google Classroom API通过 Google Classroom API 创建教师时,请求的身份验证范围不足错误
【发布时间】:2021-12-01 03:43:45
【问题描述】:

我正在尝试通过 google 课堂 API 为学生创建作业。但是,我了解到管理员不能这样做,只有教师才能做到。因此,在我们的代码中,在创建新课程后,我们将设置教师的电子邮件,这与管理员相同。但是,创建教师时代码失败。它说请求的身份验证范围不足。我尝试添加不同的额外范围,但我被此错误消息卡住了。

private static final List<String> SCOPES = 
 Arrays.asList(ClassroomScopes.CLASSROOM_COURSES, 
 ClassroomScopes.CLASSROOM_COURSEWORK_STUDENTS, 
 ClassroomScopes.CLASSROOM_COURSEWORK_ME, 
 ClassroomScopes.CLASSROOM_ROSTERS);


    Course course = new Course()
            .setName("10th Grade Biology")
            .setSection("Period 2")
            .setDescriptionHeading("Welcome to 10th Grade Biology")
            .setDescription("We'll be learning about about the structure of living creatures "
                    + "from a combination of textbooks, guest lectures, and lab work. Expect "
                    + "to be excited!")
            .setRoom("301")
            .setOwnerId("me")
            .setCourseState("PROVISIONED");

    course = service.courses().create(course).execute();
    System.out.printf("Course created: %s (%s)\n", course.getName(), course.getId());


    String courseId = course.getId();
    String teacherEmail = "admin@gmail.com";
    Teacher teacher = new Teacher().setUserId(teacherEmail);
    try {
        teacher = service.courses().teachers().create(courseId, teacher).execute();
        System.out.printf("User '%s' was added as a teacher to the course with ID '%s'.\n",
                teacher.getProfile().getName().getFullName(), courseId);
    } catch (GoogleJsonResponseException e) {
        GoogleJsonError error = e.getDetails();
        if (error.getCode() == 409) {
            System.out.printf("User '%s' is already a member of this course.\n", teacherEmail);
        } else {
            throw e;
        }
    }

这里是完整的代码:

public class ClassroomQuickstart {
private static final String APPLICATION_NAME = "Google Classroom API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";


private static final List<String> SCOPES = Arrays.asList(ClassroomScopes.CLASSROOM_COURSES, ClassroomScopes.CLASSROOM_COURSEWORK_STUDENTS, ClassroomScopes.CLASSROOM_COURSEWORK_ME, ClassroomScopes.CLASSROOM_ROSTERS);


private static final String CREDENTIALS_FILE_PATH = "/credentials.json";


private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
    // Load client secrets.
    InputStream in = ClassroomQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
    if (in == null) {
        throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
    }
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

    // Build flow and trigger user authorization request.
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
            .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
            .setAccessType("offline")
            .build();
    LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
    return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}


 public static void main(String... args) throws IOException, 
   GeneralSecurityException {
    // Build a new authorized API client service.
    final NetHttpTransport HTTP_TRANSPORT = 
   GoogleNetHttpTransport.newTrustedTransport();
    Classroom service = new Classroom.Builder(HTTP_TRANSPORT, JSON_FACTORY, 
   getCredentials(HTTP_TRANSPORT))
            .setApplicationName(APPLICATION_NAME)
            .build();

    // List the first 10 courses that the user has access to.
    ListCoursesResponse response = service.courses().list()
            .setPageSize(10)
            .execute();
    List<Course> courses = response.getCourses();
    if (courses == null || courses.size() == 0) {
        System.out.println("No courses found.");
    } else {
        System.out.println("Courses:");
        for (Course course : courses) {
            System.out.printf("%s\n", course.getName());
        }
    }


    Course course = new Course()
            .setName("10th Grade Biology")
            .setSection("Period 2")
            .setDescriptionHeading("Welcome to 10th Grade Biology")
            .setDescription("We'll be learning about about the structure of living creatures "
                    + "from a combination of textbooks, guest lectures, and lab work. Expect "
                    + "to be excited!")
            .setRoom("301")
            .setOwnerId("me")
            .setCourseState("PROVISIONED");

    course = service.courses().create(course).execute();
    System.out.printf("Course created: %s (%s)\n", course.getName(), course.getId());


    String courseId = course.getId();
    String teacherEmail = "admin@gmail.com";
    Teacher teacher = new Teacher().setUserId(teacherEmail);
    try {
        teacher = service.courses().teachers().create(courseId, teacher).execute();
        System.out.printf("User '%s' was added as a teacher to the course with ID '%s'.\n",
                teacher.getProfile().getName().getFullName(), courseId);
    } catch (GoogleJsonResponseException e) {
        GoogleJsonError error = e.getDetails();
        if (error.getCode() == 409) {
            System.out.printf("User '%s' is already a member of this course.\n", teacherEmail);
        } else {
            throw e;
        }
    }


   
//        CourseWork courseWork = new CourseWork()
//         .setCourseId(course.getId())
//          .setTitle("title")
//          .setWorkType("ASSIGNMENT")
//           .setDescription("desc");

//        service.courses().courseWork().create(course.getId(), courseWork).execute();

}

}

谢谢。

更新

根据@DaImTo'answer,添加这两个额外的配置文件修复了原始错误。 ClassroomScopes.CLASSROOM_PROFILE_EMAILS, ClassroomScopes.CLASSROOM_PROFILE_PHOTOS,

但是,我们仍然收到“调用者没有权限”错误消息。

【问题讨论】:

    标签: java google-api google-visualization google-api-java-client google-classroom


    【解决方案1】:

    corses.create方法要求授权用户必须同意以下范围。

    方法courses.teachers.create 需要以下范围之一

    现在,如果我们查看您的代码,您似乎正在使用以下范围

    List<String> SCOPES = 
     Arrays.asList(ClassroomScopes.CLASSROOM_COURSES, 
     ClassroomScopes.CLASSROOM_COURSEWORK_STUDENTS, 
     ClassroomScopes.CLASSROOM_COURSEWORK_ME, 
     ClassroomScopes.CLASSROOM_ROSTERS);
    

    这应该足以确保您有访问权限。但是,您似乎也正在使用 CREDENTIALS_FILE_PATH,这是存储用户同意的位置。现在,如果您运行您的应用程序并请求用户访问并且用户同意它。然后该用户的凭据将存储在文件中。如果您随后更改了代码中的范围,则代码仍在使用旧范围从 CREDENTIALS_FILE_PATH 读取。

    您需要强制您的应用程序再次请求用户的访问权限,这一次同意适当的范围。

    有两种方法可以做到这一点。删除 CREDENTIALS_FILE_PATH 中的文件
    名称中包含“用户”。

    或在这行代码中将“用户”更改为其他内容。

     AuthorizationCodeInstalledApp(flow, receiver).authorize("user");  change 
    

    【讨论】:

    • 您好,感谢您的回答。我添加了两个额外的配置文件范围,错误消失了。但是,我仍然得到“调用者没有权限”。
    猜你喜欢
    • 2016-04-28
    • 2021-12-12
    • 2021-11-22
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 2023-03-13
    相关资源
    最近更新 更多