Nutzer anmelden

Dies ist die zweite Schritt-für-Schritt-Anleitung zu Classroom-Add-ons. Schritt-für-Schritt-Anleitung.

In dieser Schritt-für-Schritt-Anleitung fügen Sie der Webanwendung Google Log-in hinzu. Dies ist ein für Classroom-Add-ons erforderlich. Verwenden Sie die Anmeldedaten von Autorisierungsablauf für alle zukünftigen API-Aufrufe.

Im Verlauf dieser Schritt-für-Schritt-Anleitung führen Sie die folgenden Schritte aus:

  • Konfigurieren Sie Ihre Webanwendung so, dass Sitzungsdaten in einem iFrame gespeichert werden.
  • Implementieren Sie die Google OAuth 2.0-Server-zu-Server-Anmeldung.
  • Senden Sie einen Aufruf an die OAuth 2.0 API.
  • Zusätzliche Routen erstellen, um das Autorisieren, Abmelden und Testen zu unterstützen API-Aufrufe

Anschließend können Sie Nutzer in Ihrer Webanwendung vollständig autorisieren und Aufrufe an folgende Adressen senden: Google APIs

Autorisierungsablauf verstehen

Google APIs verwenden zur Authentifizierung und Autorisierung das OAuth 2.0-Protokoll. Eine vollständige Beschreibung der OAuth-Implementierung von Google finden Sie in der OAuth-Leitfaden für Google Identity

Die Anmeldedaten Ihrer Anwendung werden in Google Cloud verwaltet. Sobald diese Implementierung eines vierstufigen Prozesses zur Authentifizierung und Autorisierung Nutzer:

  1. Fordern Sie die Autorisierung an. Geben Sie in dieser Anfrage eine Callback-URL an. Anschließend erhalten Sie eine Autorisierungs-URL.
  2. Leiten Sie den Nutzer zur Autorisierungs-URL weiter. Auf der daraufhin angezeigten Seite wird der Nutzer über die Berechtigungen, die für Ihre App erforderlich sind, und fordert ihn auf, den Zugriff zu erlauben. Wenn der Vorgang abgeschlossen ist, wird der Nutzer zur Rückruf-URL weitergeleitet.
  3. Sie erhalten einen Autorisierungscode auf Ihrer Rückrufroute. Tauschen Sie die Autorisierungscode für ein Zugriffstoken und ein Aktualisierungstoken.
  4. Rufen Sie mit den Tokens eine Google API auf.

OAuth 2.0-Anmeldedaten abrufen

Stellen Sie sicher, dass Sie OAuth-Anmeldedaten erstellt und heruntergeladen haben, wie in den Seite „Übersicht“ Ihr Projekt muss diese Anmeldedaten verwenden, um den Nutzer anzumelden.

Autorisierungsvorgang implementieren

Fügen Sie unserer Webanwendung Logik und Routen hinzu, um den beschriebenen Ablauf zu implementieren, einschließlich diese Funktionen:

  • Starten Sie den Autorisierungsvorgang, sobald Sie die Landingpage erreicht haben.
  • Fordern Sie die Autorisierung an und verarbeiten Sie die Antwort des Autorisierungsservers.
  • Löschen Sie die gespeicherten Anmeldedaten.
  • App-Berechtigungen widerrufen
  • API-Aufruf testen

Autorisierung initiieren

Ändern Sie gegebenenfalls Ihre Landingpage, um den Autorisierungsvorgang zu starten. Die kann ein Add-on zwei mögliche Status haben: Entweder befinden sich gespeicherte Tokens im oder Sie benötigen Tokens vom OAuth 2.0-Server. Ausführen einen API-Testaufruf, wenn sich in der Sitzung Tokens befinden, oder fordern Sie den Nutzer anderweitig auf. um sich anzumelden.

Python

Öffnen Sie Ihre routes.py-Datei. Legen Sie zunächst einige Konstanten Konfiguration gemäß den Sicherheitsempfehlungen für iFrames

# The file that contains the OAuth 2.0 client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# The OAuth 2.0 access scopes to request.
# These scopes must match the scopes in your Google Cloud project's OAuth Consent
# Screen: https://console.cloud.google.com/apis/credentials/consent
SCOPES = [
    "openid",
    "https://www.googleapis.com/auth/userinfo.profile",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/classroom.addons.teacher",
    "https://www.googleapis.com/auth/classroom.addons.student"
]

# Flask cookie configurations.
app.config.update(
    SESSION_COOKIE_SECURE=True,
    SESSION_COOKIE_HTTPONLY=True,
    SESSION_COOKIE_SAMESITE="None",
)

Wechseln Sie zu Ihrer zusätzlichen Landingpage-Route (im Beispiel ist dies /classroom-addon). -Datei). Fügen Sie Logik zum Rendern einer Anmeldeseite hinzu, falls die Sitzung keine die „Anmeldedaten“ .

@app.route("/classroom-addon")
def classroom_addon():
    if "credentials" not in flask.session:
        return flask.render_template("authorization.html")

    return flask.render_template(
        "addon-discovery.html",
        message="You've reached the addon discovery page.")

Java

Den Code für diese Schritt-für-Schritt-Anleitung finden Sie im Modul step_02_sign_in.

Öffnen Sie die Datei application.properties und fügen Sie eine Sitzungskonfiguration hinzu, entspricht den Sicherheitsempfehlungen für iFrames.

# iFrame security recommendations call for cookies to have the HttpOnly and
# secure attribute set
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true

# Ensures that the session is maintained across the iframe and sign-in pop-up.
server.servlet.session.cookie.same-site=none

Dienstklasse erstellen (AuthService.java im Modul step_02_sign_in) um die Logik hinter den Endpunkten in der Controller-Datei zu verarbeiten Den Weiterleitungs-URI, den Speicherort der Clientschlüsseldatei und die Bereiche, die Ihr Add-on verwendet erfordert. Mit dem Weiterleitungs-URI werden Nutzer an eine bestimmte URI weitergeleitet nachdem er Ihre App autorisiert hat. Weitere Informationen finden Sie im Abschnitt Projekteinrichtung der README.md im Quellcode für Informationen dazu, wo Sie Ihre client_secret.json-Datei.

@Service
public class AuthService {
    private static final String REDIRECT_URI = "https://localhost:5000/callback";
    private static final String CLIENT_SECRET_FILE = "client_secret.json";
    private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

    private static final String[] REQUIRED_SCOPES = {
        "https://www.googleapis.com/auth/userinfo.profile",
        "https://www.googleapis.com/auth/userinfo.email",
        "https://www.googleapis.com/auth/classroom.addons.teacher",
        "https://www.googleapis.com/auth/classroom.addons.student"
    };

    /** Creates and returns a Collection object with all requested scopes.
    *   @return Collection of scopes requested by the application.
    */
    public static Collection<String> getScopes() {
        return new ArrayList<>(Arrays.asList(REQUIRED_SCOPES));
    }
}

Öffnen Sie die Controller-Datei (AuthController.java im Ordner step_02_sign_in). Modul) und fügen Sie der Landing Route Logik hinzu, um die Anmeldeseite zu rendern, wenn das Sitzung enthält den Schlüssel credentials nicht.

@GetMapping(value = {"/start-auth-flow"})
public String startAuthFlow(Model model) {
    try {
        return "authorization";
    } catch (Exception e) {
        return onError(e.getMessage(), model);
    }
}

@GetMapping(value = {"/addon-discovery"})
public String addon_discovery(HttpSession session, Model model) {
    try {
        if (session == null || session.getAttribute("credentials") == null) {
            return startAuthFlow(model);
        }
        return "addon-discovery";
    } catch (Exception e) {
        return onError(e.getMessage(), model);
    }
}

Ihre Autorisierungsseite sollte einen Link oder eine Schaltfläche enthalten, über die Nutzer in". Dadurch sollte der Nutzer zur Route authorize weitergeleitet werden.

Autorisierung anfordern

Erstellen Sie eine Authentifizierung für den Nutzer und leiten Sie ihn an diese weiter, um die Autorisierung anzufordern. URL Diese URL enthält verschiedene Informationen, wie z. B. den Umfang angefordert, die Zielroute für nach der Autorisierung und die Client-ID. Sie finden sie in diesem Beispiel für eine Autorisierungs-URL.

Python

Fügen Sie der Datei routes.py den folgenden Import hinzu.

import google_auth_oauthlib.flow

Neue Route /authorize erstellen. Instanz von erstellen google_auth_oauthlib.flow.Flow; empfehlen wir die Verwendung der from_client_secrets_file-Methode hinzu.

@app.route("/authorize")
def authorize():
    # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow
    # steps.
    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
        CLIENT_SECRETS_FILE, scopes=SCOPES)

Legen Sie redirect_uri für flow fest. Dies ist die Route, zu der Nutzer nach der Autorisierung Ihrer App zurückgeben. Das ist /callback in den folgenden Beispiel.

# The URI created here must exactly match one of the authorized redirect
# URIs for the OAuth 2.0 client, which you configured in the API Console. If
# this value doesn't match an authorized URI, you will get a
# "redirect_uri_mismatch" error.
flow.redirect_uri = flask.url_for("callback", _external=True)

Erstellen Sie mit dem Flussobjekt authorization_url und state. Geschäft das state in der Sitzung; wird die Authentizität Serverantwort später. Leiten Sie die Nutzenden schließlich authorization_url

authorization_url, state = flow.authorization_url(
    # Enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type="offline",
    # Enable incremental authorization. Recommended as a best practice.
    include_granted_scopes="true")

# Store the state so the callback can verify the auth server response.
flask.session["state"] = state

# Redirect the user to the OAuth authorization URL.
return flask.redirect(authorization_url)

Java

Fügen Sie der Datei AuthService.java die folgenden Methoden hinzu, um die Methode und verwenden Sie es dann zum Abrufen der Autorisierungs-URL:

  • Die Methode getClientSecrets() liest die Clientschlüsseldatei und erstellt Ein GoogleClientSecrets-Objekt.
  • Mit der Methode getFlow() wird eine Instanz von GoogleAuthorizationCodeFlow erstellt.
  • Die Methode authorize() verwendet das GoogleAuthorizationCodeFlow-Objekt, das state-Parameter und den Weiterleitungs-URI zum Abrufen der Autorisierungs-URL. Der Parameter state wird verwendet, um die Authentizität der Antwort zu prüfen. vom Autorisierungsserver. Die Methode gibt dann eine Karte mit dem Autorisierungs-URL und den Parameter state.
/** Reads the client secret file downloaded from Google Cloud.
 *   @return GoogleClientSecrets read in from client secret file. */
public GoogleClientSecrets getClientSecrets() throws Exception {
    try {
        InputStream in = SignInApplication.class.getClassLoader()
            .getResourceAsStream(CLIENT_SECRET_FILE);
        if (in == null) {
            throw new FileNotFoundException("Client secret file not found: "
                +   CLIENT_SECRET_FILE);
        }
        GoogleClientSecrets clientSecrets = GoogleClientSecrets
            .load(JSON_FACTORY, new InputStreamReader(in));
        return clientSecrets;
    } catch (Exception e) {
        throw e;
    }
}

/** Builds and returns authorization code flow.
*   @return GoogleAuthorizationCodeFlow object used to retrieve an access
*   token and refresh token for the application.
*   @throws Exception if reading client secrets or building code flow object
*   is unsuccessful.
*/
public GoogleAuthorizationCodeFlow getFlow() throws Exception {
    try {
        GoogleAuthorizationCodeFlow authorizationCodeFlow =
            new GoogleAuthorizationCodeFlow.Builder(
                HTTP_TRANSPORT,
                JSON_FACTORY,
                getClientSecrets(),
                getScopes())
                .setAccessType("offline")
                .build();
        return authorizationCodeFlow;
    } catch (Exception e) {
        throw e;
    }
}

/** Builds and returns a map with the authorization URL, which allows the
*   user to give the app permission to their account, and the state parameter,
*   which is used to prevent cross site request forgery.
*   @return map with authorization URL and state parameter.
*   @throws Exception if building the authorization URL is unsuccessful.
*/
public HashMap authorize() throws Exception {
    HashMap<String, String> authDataMap = new HashMap<>();
    try {
        String state = new BigInteger(130, new SecureRandom()).toString(32);
        authDataMap.put("state", state);

        GoogleAuthorizationCodeFlow flow = getFlow();
        String authUrl = flow
            .newAuthorizationUrl()
            .setState(state)
            .setRedirectUri(REDIRECT_URI)
            .build();
        String url = authUrl;
        authDataMap.put("url", url);

        return authDataMap;
    } catch (Exception e) {
        throw e;
    }
}

Verwenden Sie die Konstruktor-Einschleusung, um eine Instanz der Dienstklasse in der Controller-Klasse.

/** Declare AuthService to be used in the Controller class constructor. */
private final AuthService authService;

/** AuthController constructor. Uses constructor injection to instantiate
*   the AuthService and UserRepository classes.
*   @param authService the service class that handles the implementation logic
*   of requests.
*/
public AuthController(AuthService authService) {
    this.authService = authService;
}

Fügen Sie der Controller-Klasse den Endpunkt /authorize hinzu. Dieser Endpunkt ruft auf Die AuthService-Methode authorize() zum Abrufen des state-Parameters und die Autorisierungs-URL. Dann speichert der Endpunkt die state. in der Sitzung und leitet die Nutzer an die Autorisierungs-URL weiter.

/** Redirects the sign-in pop-up to the authorization URL.
*   @param response the current response to pass information to.
*   @param session the current session.
*   @throws Exception if redirection to the authorization URL is unsuccessful.
*/
@GetMapping(value = {"/authorize"})
public void authorize(HttpServletResponse response, HttpSession session)
    throws Exception {
    try {
        HashMap authDataMap = authService.authorize();
        String authUrl = authDataMap.get("url").toString();
        String state = authDataMap.get("state").toString();
        session.setAttribute("state", state);
        response.sendRedirect(authUrl);
    } catch (Exception e) {
        throw e;
    }
}

Serverantwort verarbeiten

Nach der Autorisierung kehrt der Nutzer zur Route redirect_uri vom vorherigen Schritt. Im vorherigen Beispiel lautet die Route /callback.

Sie erhalten ein code in der Antwort, wenn der Nutzer vom Autorisierungsseite aufzurufen. Tauschen Sie dann den Code gegen Zugriffs- und Aktualisierungstokens aus:

Python

Fügen Sie der Flask-Serverdatei die folgenden Importe hinzu.

import google.oauth2.credentials
import googleapiclient.discovery

Fügen Sie die Route zu Ihrem Server hinzu. Weitere Instanz von erstellen google_auth_oauthlib.flow.Flow, aber diesmal den im vorherigen Schritt.

@app.route("/callback")
def callback():
    state = flask.session["state"]

    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
        CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
    flow.redirect_uri = flask.url_for("callback", _external=True)

Fordern Sie als Nächstes Zugriffs- und Aktualisierungstokens an. Glücklicherweise kann auch das flow-Objekt enthält zu diesem Zweck die Methode fetch_token. Die Methode erwartet Entweder das Argument code oder das Argument authorization_response. Verwenden Sie die Methode authorization_response, da es sich um die vollständige URL aus der Anfrage handelt.

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

Ihre Anmeldedaten sind jetzt vollständig. Speichern Sie sie in der Sitzung, können über andere Methoden oder Routen abgerufen werden und werden dann an ein Add-on weitergeleitet. Landingpage.

credentials = flow.credentials
flask.session["credentials"] = {
    "token": credentials.token,
    "refresh_token": credentials.refresh_token,
    "token_uri": credentials.token_uri,
    "client_id": credentials.client_id,
    "client_secret": credentials.client_secret,
    "scopes": credentials.scopes
}

# Close the pop-up by rendering an HTML page with a script that redirects
# the owner and closes itself. This can be done with a bit of JavaScript:
# <script>
#     window.opener.location.href = "{{ url_for('classroom_addon') }}";
#     window.close();
# </script>
return flask.render_template("close-me.html")

Java

Fügen Sie Ihrer Dienstklasse eine Methode hinzu, die das Objekt Credentials zurückgibt, indem Übergabe des Autorisierungscodes, der von der Weiterleitung abgerufen wurde, die von Autorisierungs-URL Dieses Credentials-Objekt wird später zum Abrufen das Zugriffstoken und das Aktualisierungstoken.

/** Returns the required credentials to access Google APIs.
*   @param authorizationCode the authorization code provided by the
*   authorization URL that's used to obtain credentials.
*   @return the credentials that were retrieved from the authorization flow.
*   @throws Exception if retrieving credentials is unsuccessful.
*/
public Credential getAndSaveCredentials(String authorizationCode) throws Exception {
    try {
        GoogleAuthorizationCodeFlow flow = getFlow();
        GoogleClientSecrets googleClientSecrets = getClientSecrets();
        TokenResponse tokenResponse = flow.newTokenRequest(authorizationCode)
            .setClientAuthentication(new ClientParametersAuthentication(
                googleClientSecrets.getWeb().getClientId(),
                googleClientSecrets.getWeb().getClientSecret()))
            .setRedirectUri(REDIRECT_URI)
            .execute();
        Credential credential = flow.createAndStoreCredential(tokenResponse, null);
        return credential;
    } catch (Exception e) {
        throw e;
    }
}

Fügen Sie dem Controller einen Endpunkt für den Weiterleitungs-URI hinzu. Rufen Sie die Autorisierungscode und state-Parameter aus der Anfrage. Vergleichen state-Parameter für das in der Sitzung gespeicherte Attribut state. Wenn sie und fahre dann mit dem Autorisierungsvorgang fort. Stimmen sie nicht überein, gibt einen Fehler zurück.

Rufen Sie dann die AuthService-Methode getAndSaveCredentials auf und übergeben Sie die Autorisierungscode als Parameter verwendet. Nach dem Abrufen von Credentials -Objekt enthält, speichern Sie es in der Sitzung. Schließen Sie dann das Dialogfeld der Nutzer zur Landingpage des Add-ons weitergeleitet wird.

/** Handles the redirect URL to grant the application access to the user's
*   account.
*   @param request the current request used to obtain the authorization code
*   and state parameter from.
*   @param session the current session.
*   @param response the current response to pass information to.
*   @param model the Model interface to pass error information that's
*   displayed on the error page.
*   @return the close-pop-up template if authorization is successful, or the
*   onError method to handle and display the error message.
*/
@GetMapping(value = {"/callback"})
public String callback(HttpServletRequest request, HttpSession session,
    HttpServletResponse response, Model model) {
    try {
        String authCode = request.getParameter("code");
        String requestState = request.getParameter("state");
        String sessionState = session.getAttribute("state").toString();
        if (!requestState.equals(sessionState)) {
            response.setStatus(401);
            return onError("Invalid state parameter.", model);
        }
        Credential credentials = authService.getAndSaveCredentials(authCode);
        session.setAttribute("credentials", credentials);
        return "close-pop-up";
    } catch (Exception e) {
        return onError(e.getMessage(), model);
    }
}

API-Aufruf testen

Wenn der Vorgang abgeschlossen ist, können Sie jetzt Aufrufe an Google APIs senden.

Sie können beispielsweise die Profilinformationen des Nutzers anfordern. Sie können das Nutzerinformationen aus der OAuth 2.0 API.

Python

Lesen Sie die Dokumentation zum OAuth 2.0 Discovery API Rufen Sie damit ein ausgefülltes UserInfo-Objekt ab.

# Retrieve the credentials from the session data and construct a
# Credentials instance.
credentials = google.oauth2.credentials.Credentials(
    **flask.session["credentials"])

# Construct the OAuth 2.0 v2 discovery API library.
user_info_service = googleapiclient.discovery.build(
    serviceName="oauth2", version="v2", credentials=credentials)

# Request and store the username in the session.
# This allows it to be used in other methods or in an HTML template.
flask.session["username"] = (
    user_info_service.userinfo().get().execute().get("name"))

Java

Erstellen Sie eine Methode in der Dienstklasse, die ein UserInfo-Objekt mithilfe von Credentials als Parameter verwenden.

/** Obtains the Userinfo object by passing in the required credentials.
*   @param credentials retrieved from the authorization flow.
*   @return the Userinfo object for the currently signed-in user.
*   @throws IOException if creating UserInfo service or obtaining the
*   Userinfo object is unsuccessful.
*/
public Userinfo getUserInfo(Credential credentials) throws IOException {
    try {
        Oauth2 userInfoService = new Oauth2.Builder(
            new NetHttpTransport(),
            new GsonFactory(),
            credentials).build();
        Userinfo userinfo = userInfoService.userinfo().get().execute();
        return userinfo;
    } catch (Exception e) {
        throw e;
    }
}

Fügen Sie dem Controller, der die E-Mail-Adresse des Nutzers anzeigt, den Endpunkt /test hinzu.

/** Returns the test request page with the user's email.
*   @param session the current session.
*   @param model the Model interface to pass error information that's
*   displayed on the error page.
*   @return the test page that displays the current user's email or the
*   onError method to handle and display the error message.
*/
@GetMapping(value = {"/test"})
public String test(HttpSession session, Model model) {
    try {
        Credential credentials = (Credential) session.getAttribute("credentials");
        Userinfo userInfo = authService.getUserInfo(credentials);
        String userInfoEmail = userInfo.getEmail();
        if (userInfoEmail != null) {
            model.addAttribute("userEmail", userInfoEmail);
        } else {
            return onError("Could not get user email.", model);
        }
        return "test";
    } catch (Exception e) {
        return onError(e.getMessage(), model);
    }
}

Anmeldedaten löschen

Du kannst „löschen“ die Anmeldedaten eines Nutzers, indem er sie aus der aktuellen Sitzung entfernt. So können Sie die Weiterleitung auf der Landingpage des Add-ons testen.

Wir empfehlen, den Hinweis anzuzeigen, dass sich der Nutzer zuvor abgemeldet hat um sie auf die Landingpage des Add-ons weiterzuleiten. Ihre App sollte die Autorisierungsablauf zum Abrufen neuer Anmeldedaten, aber Nutzer werden nicht dazu aufgefordert, Autorisieren Sie Ihre App noch einmal.

Python

@app.route("/clear")
def clear_credentials():
    if "credentials" in flask.session:
        del flask.session["credentials"]
        del flask.session["username"]

    return flask.render_template("signed-out.html")

Alternativ können Sie flask.session.clear() verwenden. Dies kann jedoch einen unbeabsichtigten Auswirkungen, wenn Sie andere Werte in der Sitzung gespeichert haben.

Java

Fügen Sie im Controller einen /clear-Endpunkt hinzu.

/** Clears the credentials in the session and returns the sign-out
*   confirmation page.
*   @param session the current session.
*   @return the sign-out confirmation page.
*/
@GetMapping(value = {"/clear"})
public String clear(HttpSession session) {
    try {
        if (session != null && session.getAttribute("credentials") != null) {
            session.removeAttribute("credentials");
        }
        return "sign-out";
    } catch (Exception e) {
        return onError(e.getMessage(), model);
    }
}

Berechtigung der App widerrufen

Ein Nutzer kann die Berechtigung deiner App widerrufen, indem er eine POST-Anfrage an https://oauth2.googleapis.com/revoke. Die Anfrage sollte die ein Zugriffstoken hinzufügen.

Python

import requests

@app.route("/revoke")
def revoke():
    if "credentials" not in flask.session:
        return flask.render_template("addon-discovery.html",
                            message="You need to authorize before " +
                            "attempting to revoke credentials.")

    credentials = google.oauth2.credentials.Credentials(
        **flask.session["credentials"])

    revoke = requests.post(
        "https://oauth2.googleapis.com/revoke",
        params={"token": credentials.token},
        headers={"content-type": "application/x-www-form-urlencoded"})

    if "credentials" in flask.session:
        del flask.session["credentials"]
        del flask.session["username"]

    status_code = getattr(revoke, "status_code")
    if status_code == 200:
        return flask.render_template("authorization.html")
    else:
        return flask.render_template(
            "index.html", message="An error occurred during revocation!")

Java

Fügen Sie der Dienstklasse eine Methode hinzu, die einen Aufruf an den Widerrufsendpunkt sendet.

/** Revokes the app's permissions to the user's account.
*   @param credentials retrieved from the authorization flow.
*   @return response entity returned from the HTTP call to obtain response
*   information.
*   @throws RestClientException if the POST request to the revoke endpoint is
*   unsuccessful.
*/
public ResponseEntity<String> revokeCredentials(Credential credentials) throws RestClientException {
    try {
        String accessToken = credentials.getAccessToken();
        String url = "https://oauth2.googleapis.com/revoke?token=" + accessToken;

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE);
        HttpEntity<Object> httpEntity = new HttpEntity<Object>(httpHeaders);
        ResponseEntity<String> responseEntity = new RestTemplate().exchange(
            url,
            HttpMethod.POST,
            httpEntity,
            String.class);
        return responseEntity;
    } catch (RestClientException e) {
        throw e;
    }
}

Fügen Sie dem Controller den Endpunkt /revoke hinzu, der die Sitzung löscht, und leitet den Nutzer auf die Autorisierungsseite weiter, wenn der Widerruf erfolgreich war.

/** Revokes the app's permissions and returns the authorization page.
*   @param session the current session.
*   @return the authorization page.
*   @throws Exception if revoking access is unsuccessful.
*/
@GetMapping(value = {"/revoke"})
public String revoke(HttpSession session) throws Exception {
    try {
        if (session != null && session.getAttribute("credentials") != null) {
            Credential credentials = (Credential) session.getAttribute("credentials");
            ResponseEntity responseEntity = authService.revokeCredentials(credentials);
            Integer httpStatusCode = responseEntity.getStatusCodeValue();

            if (httpStatusCode != 200) {
                return onError("There was an issue revoking access: " +
                    responseEntity.getStatusCode(), model);
            }
            session.removeAttribute("credentials");
        }
        return startAuthFlow(model);
    } catch (Exception e) {
        return onError(e.getMessage(), model);
    }
}

Add-on testen

Melden Sie sich in Google Classroom an. als einer Ihrer Lehrer-Testnutzer. Gehen Sie zum Tab Kursaufgaben und erstellen Sie eine neue Aufgabe. Klicken Sie unter dem Textbereich auf die Schaltfläche Add-ons. und wählen Sie Ihr Add-on aus. Der iFrame wird geöffnet und das Add-on lädt die URI für die Anhangseinrichtung, den Sie in der App des GWM SDK angegeben haben. Konfiguration Seite.

Glückwunsch! Sie können nun mit dem nächsten Schritt fortfahren: Wiederholungen Besuche Ihres Add-ons.