Dies ist die zweite Anleitung in der Reihe zu Classroom-Add-ons.
In dieser Anleitung fügen Sie der Webanwendung Google Log-in hinzu. Dies ist für Classroom-Add-ons erforderlich. Verwenden Sie die Anmeldedaten aus diesem Autorisierungsablauf für alle zukünftigen Aufrufe der API.
In dieser Anleitung führen Sie die folgenden Schritte aus:
- Konfigurieren Sie Ihre Webanwendung so, dass Sitzungsdaten in einem iFrame gespeichert werden.
- Implementieren Sie den Server-zu-Server-Anmeldevorgang von Google OAuth 2.0.
- Rufen Sie die OAuth 2.0 API auf.
- Erstellen Sie zusätzliche Routen, um die Autorisierung, Abmeldung und das Testen von API-Aufrufen zu unterstützen.
Danach können Sie Nutzer in Ihrer Webanwendung vollständig autorisieren und Google APIs aufrufen.
Autorisierungsablauf
Google APIs verwenden zur Authentifizierung und Autorisierung das OAuth 2.0-Protokoll. Eine vollständige Beschreibung der OAuth-Implementierung von Google finden Sie im OAuth-Leitfaden für Google Identity.
Die Anmeldedaten Ihrer Anwendung werden in Google Cloud verwaltet. Nachdem Sie diese erstellt haben, implementieren Sie einen vierstufigen Prozess zur Authentifizierung und Autorisierung eines Nutzers:
- Autorisierung anfordern. Geben Sie im Rahmen dieser Anfrage eine Callback-URL an. Danach erhalten Sie eine Autorisierungs-URL.
- Leiten Sie den Nutzer zur Autorisierungs-URL weiter. Auf der angezeigten Seite werden dem Nutzer die Berechtigungen mitgeteilt, die Ihre App benötigt, und er wird aufgefordert, den Zugriff zuzulassen. Danach wird der Nutzer an die Callback-URL weitergeleitet.
- Sie erhalten einen Autorisierungscode über Ihre Rückrufroute. Tausche den Autorisierungscode gegen ein Zugriffstoken und ein Aktualisierungstoken aus.
- Rufen Sie mit den Tokens eine Google API auf.
OAuth 2.0-Anmeldedaten abrufen
Sie müssen OAuth-Anmeldedaten wie auf der Übersichtsseite beschrieben erstellt und heruntergeladen haben. In Ihrem Projekt müssen diese Anmeldedaten verwendet werden, um den Nutzer anzumelden.
Autorisierungsablauf implementieren
Fügen Sie unserer Webanwendung Logik und Routen hinzu, um den beschriebenen Ablauf zu realisieren, einschließlich der folgenden Funktionen:
- Starte den Autorisierungsvorgang, sobald du die Landingpage aufgerufen hast.
- Autorisierung anfordern und die Antwort des Autorisierungsservers verarbeiten.
- Löschen Sie die gespeicherten Anmeldedaten.
- Widerrufen Sie die Berechtigungen der App.
- API-Aufruf testen
Autorisierung initiieren
Ändern Sie bei Bedarf Ihre Landingpage, um den Autorisierungsablauf zu starten. Das Add-on kann sich in zwei möglichen Status befinden: Entweder sind in der aktuellen Sitzung gespeicherte Tokens vorhanden oder Sie müssen Tokens vom OAuth 2.0-Server abrufen. Führe einen Test-API-Aufruf aus, wenn sich in der Sitzung Tokens befinden, oder fordere den Nutzer anderweitig auf, sich anzumelden.
Python
Öffnen Sie Ihre routes.py
-Datei. Legen Sie zuerst einige Konstanten und die Cookie-Konfiguration gemäß den Sicherheitsempfehlungen für iFrames fest.
# 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",
)
Rufen Sie den Landingpage-Pfad für das Add-on auf (in der Beispieldatei /classroom-addon
). Fügen Sie eine Logik hinzu, um eine Anmeldeseite zu rendern, wenn die Sitzung den Schlüssel „credentials“ nicht enthält.
@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, die den Sicherheitsempfehlungen für iframes entspricht.
# 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
Erstelle eine Dienstklasse (AuthService.java
im Modul step_02_sign_in
), um die Logik hinter den Endpunkten in der Controllerdatei zu verarbeiten, und richte den Weiterleitungs-URI, den Speicherort der Clientschlüsseldatei und die erforderlichen Bereiche für dein Add-on ein. Über den Weiterleitungs-URI werden Nutzer an einen bestimmten URI weitergeleitet, nachdem sie deine App autorisiert haben. Im Abschnitt „Project Set Up“ (Projekteinrichtung) der README.md
im Quellcode findest du Informationen dazu, wo du die client_secret.json
-Datei platzieren solltest.
@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 Controllerdatei (AuthController.java
im step_02_sign_in
-Modul) und fügen Sie der Landingpage-Route Logik hinzu, um die Anmeldeseite zu rendern, wenn die Sitzung den Schlüssel credentials
nicht enthält.
@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 sich der Nutzer „anmelden“ kann. Wenn der Nutzer darauf klickt, sollte er zur Route authorize
weitergeleitet werden.
Autorisierung anfordern
Wenn du eine Autorisierung anfordern möchtest, musst du eine Authentifizierungs-URL erstellen und den Nutzer dorthin weiterleiten. Diese URL enthält mehrere Informationen, z. B. die angeforderten Bereiche, die Zielroute für nach der Autorisierung und die Client-ID der Webanwendung. Sie finden sie in dieser Beispielautorisierungs-URL.
Python
Fügen Sie der Datei routes.py
den folgenden Import hinzu.
import google_auth_oauthlib.flow
Erstellen Sie eine neue Route /authorize
. Erstelle eine Instanz von google_auth_oauthlib.flow.Flow
. Wir empfehlen dringend, dazu die integrierte Methode from_client_secrets_file
zu verwenden.
@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 die redirect_uri
von flow
fest. Dies ist die Route, zu der Nutzer nach der Autorisierung Ihrer App zurückkehren sollen. Im folgenden Beispiel ist das /callback
.
# 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)
Verwenden Sie das Ablaufobjekt, um authorization_url
und state
zu erstellen. Speichere die state
in der Sitzung. Sie wird später verwendet, um die Authentizität der Serverantwort zu überprüfen. Leiten Sie den Nutzer abschließend zur authorization_url
weiter.
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 das Ablaufobjekt zu instanziieren und dann die Autorisierungs-URL abzurufen:
- Die Methode
getClientSecrets()
liest die Clientsecret-Datei und erstellt einGoogleClientSecrets
-Objekt. - Mit der Methode
getFlow()
wird eine Instanz vonGoogleAuthorizationCodeFlow
erstellt. - Bei der
authorize()
-Methode werden dasGoogleAuthorizationCodeFlow
-Objekt, derstate
-Parameter und die Weiterleitungs-URI verwendet, um die Autorisierungs-URL abzurufen. Mit dem Parameterstate
wird die Authentizität der Antwort vom Autorisierungsserver überprüft. Die Methode gibt dann eine Map mit der Autorisierungs-URL und dem Parameterstate
zurück.
/** 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-Injection, um eine Instanz der Dienstklasse in der Controller-Klasse zu erstellen.
/** 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 die AuthService-Methode authorize()
auf, um den Parameter state
und die Autorisierungs-URL abzurufen. Anschließend speichert der Endpunkt den Parameter state
in der Sitzung und leitet die Nutzer zur 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 zum redirect_uri
-Pfad aus dem vorherigen Schritt zurück. Im obigen Beispiel ist dies /callback
.
Du erhältst eine code
in der Antwort, wenn der Nutzer von der Autorisierungsseite zurückkehrt. Tausche den Code dann gegen Zugriffs- und Aktualisierungstokens ein:
Python
Fügen Sie Ihrer Flask-Serverdatei die folgenden Importe hinzu.
import google.oauth2.credentials
import googleapiclient.discovery
Fügen Sie die Route Ihrem Server hinzu. Erstellen Sie eine weitere Instanz von google_auth_oauthlib.flow.Flow
, verwenden Sie dabei aber den im vorherigen Schritt gespeicherten Status.
@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)
Fordere als Nächstes Zugriffs- und Aktualisierungstokens an. Glücklicherweise enthält das flow
-Objekt auch die Methode fetch_token
, um dies zu erreichen. Die Methode erwartet entweder das code
- oder das authorization_response
-Argument. Verwenden Sie die authorization_response
, da dies die vollständige URL aus der Anfrage ist.
authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)
Sie haben jetzt vollständige Anmeldedaten. Speichern Sie sie in der Sitzung, damit sie mit anderen Methoden oder Routen abgerufen werden können, und leiten Sie sie dann zu einer Add-on-Landingpage weiter.
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 Credentials
-Objekt zurückgibt, indem Sie den Autorisierungscode übergeben, der über die Autorisierungs-URL aus der Weiterleitung abgerufen wurde. Dieses Credentials
-Objekt wird später verwendet, um das Zugriffs- und Aktualisierungstoken abzurufen.
/** 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 Ihren Weiterleitungs-URI hinzu. Rufe den Autorisierungscode und den Parameter state
aus der Anfrage ab. Vergleichen Sie diesen state
-Parameter mit dem in der Sitzung gespeicherten state
-Attribut. Wenn sie übereinstimmen, fahren Sie mit dem Autorisierungsvorgang fort. Wenn sie nicht übereinstimmen, muss ein Fehler zurückgegeben werden.
Rufe dann die Methode AuthService
getAndSaveCredentials
auf und übergebe den Autorisierungscode als Parameter. Nachdem du das Credentials
-Objekt abgerufen hast, speichere es in der Sitzung. Schließe dann das Dialogfeld und leite den Nutzer zur Landingpage des Add-ons weiter.
/** 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
Nachdem der Ablauf abgeschlossen ist, können Sie jetzt Google APIs aufrufen.
Fordere beispielsweise die Profilinformationen des Nutzers an. Sie können die Informationen des Nutzers über die OAuth 2.0 API anfordern.
Python
Lies dir die Dokumentation zur OAuth 2.0 Discovery API durch. Verwende sie, um ein ausgefülltes UserInfo-Objekt abzurufen.
# 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
Erstelle in der Dienstklasse eine Methode, die ein UserInfo
-Objekt mit Credentials
als Parameter erstellt.
/** 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, in dem die E-Mail-Adresse des Nutzers angezeigt wird, 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
Sie können die Anmeldedaten eines Nutzers löschen, indem Sie sie aus der aktuellen Sitzung entfernen. So können Sie die Weiterleitung auf der Landingpage des Add-ons testen.
Wir empfehlen, einen Hinweis darauf anzuzeigen, dass sich der Nutzer abgemeldet hat, bevor er zur Add-on-Landingpage weitergeleitet wird. Ihre App sollte den Autorisierungsvorgang durchlaufen, um neue Anmeldedaten zu erhalten. Nutzer werden jedoch nicht aufgefordert, Ihre App noch einmal zu autorisieren.
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 auch flask.session.clear()
verwenden. Dies kann jedoch unbeabsichtigte Auswirkungen haben, wenn in der Sitzung andere Werte gespeichert sind.
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 Ihrer App widerrufen, indem er eine POST
-Anfrage an https://oauth2.googleapis.com/revoke
sendet. Die Anfrage muss das Zugriffstoken des Nutzers enthalten.
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 den Widerrufs-Endpunkt aufruft.
/** 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 einen Endpunkt (/revoke
) hinzu, der die Sitzung beendet und den Nutzer zur Autorisierungsseite weiterleitet, 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 als einer Ihrer Lehrkraft-Testnutzer an. Gehen Sie zum Tab Kursaufgaben und erstellen Sie eine neue Aufgabe. Klicken Sie unter dem Textfeld auf die Schaltfläche Add-ons und wählen Sie das gewünschte Add-on aus. Der Iframe wird geöffnet und das Add-on lädt den URI für die Einrichtung von Anhängen, den Sie auf der Seite App-Konfiguration des GWM SDK angegeben haben.
Glückwunsch! Sie können mit dem nächsten Schritt fortfahren: Wiederkehrende Besuche Ihres Add-ons verwalten.