Dies ist die zweite Schritt-für-Schritt-Anleitung der Reihe zu Classroom-Add-ons.
In dieser Anleitung fügen Sie der Webanwendung den Google Log-in hinzu. Dies ist ein erforderliches Verhalten für Classroom-Add-ons. 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 Web-App so, dass Sitzungsdaten in einem iFrame verwaltet 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 API-Aufrufe zu autorisieren, abzumelden und zu testen.
Danach können Sie Nutzer in Ihrer Webanwendung vollständig autorisieren und Aufrufe an Google APIs senden.
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, müssen Sie einen vierstufigen Prozess implementieren, um einen Nutzer zu authentifizieren und zu autorisieren:
- Autorisierung anfordern. Geben Sie im Rahmen dieser Anfrage eine Callback-URL an. Wenn der Vorgang abgeschlossen ist, erhalten Sie eine Autorisierungs-URL.
- Leiten Sie den Nutzer zur Autorisierungs-URL weiter. Auf der resultierenden Seite werden dem Nutzer die von Ihrer App benötigten Berechtigungen angezeigt und er wird aufgefordert, den Zugriff zu erlauben. Anschließend wird der Nutzer zur Callback-URL weitergeleitet.
- Sie erhalten einen Autorisierungscode an Ihrem Rückruf-Endpunkt. Tauschen Sie den Autorisierungscode gegen ein Zugriffstoken und ein Aktualisierungstoken ein.
- Google-API mit den Tokens aufrufen
OAuth 2.0-Anmeldedaten abrufen
Sie haben OAuth-Anmeldedaten erstellt und heruntergeladen, wie auf der Übersichtsseite beschrieben. Ihr Projekt muss diese Anmeldedaten verwenden, um den Nutzer anzumelden.
Autorisierungsvorgang implementieren
Fügen Sie unserer Web-App Logik und Routen hinzu, um den beschriebenen Ablauf zu realisieren, einschließlich der folgenden Funktionen:
- Starten Sie den Autorisierungsvorgang, sobald Sie die Landingpage aufrufen.
- 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 Autorisierungsvorgang 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ühren Sie einen Test-API-Aufruf aus, wenn in der Sitzung Tokens vorhanden sind. Fordern Sie den Nutzer andernfalls auf, sich anzumelden.
Python
Öffnen Sie Ihre routes.py
-Datei. Legen Sie zuerst einige Konstanten und unsere Cookie-Konfiguration gemäß den iFrame-Sicherheitsempfehlungen 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 die Landingpage Ihres Add-ons auf (in der Beispieldatei ist das /classroom-addon
). Fügen Sie Logik hinzu, um eine Anmeldeseite zu rendern, wenn die Sitzung nicht den Schlüssel „credentials“ 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
Der Code für diese Anleitung befindet sich 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
Erstellen Sie eine Dienstklasse (AuthService.java
im Modul step_02_sign_in
), um die Logik hinter den Endpunkten in der Controller-Datei zu verarbeiten und den Weiterleitungs-URI, den Speicherort der Datei mit den Client-Secrets und die Bereiche einzurichten, die für Ihr Add-on erforderlich sind. Der Weiterleitungs-URI wird verwendet, um Ihre Nutzer nach der Autorisierung Ihrer App zu einem bestimmten URI weiterzuleiten. Weitere Informationen dazu, wo Sie die Datei client_secret.json
platzieren müssen, finden Sie im Abschnitt „Projekteinrichtung“ der README.md
im Quellcode.
@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 Modul step_02_sign_in
) und fügen Sie der Landing-Route Logik hinzu, um die Anmeldeseite zu rendern, wenn die Sitzung nicht den Schlüssel credentials
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
Um die Autorisierung anzufordern, erstellen Sie eine Authentifizierungs-URL und leiten Sie den Nutzer zu dieser URL weiter. Diese URL enthält mehrere Informationen, z. B. die angeforderten Bereiche, die Zielroute nach der Autorisierung und die Client-ID der Web-App. Hier finden Sie ein Beispiel für eine Autorisierungs-URL.
Python
Fügen Sie der Datei routes.py
den folgenden Import hinzu.
import google_auth_oauthlib.flow
Erstellen Sie eine neue Route /authorize
. Erstellen Sie eine Instanz von google_auth_oauthlib.flow.Flow
. Wir empfehlen dringend, dazu die enthaltene 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 den redirect_uri
von flow
fest. Dies ist die Route, zu der Nutzer nach der Autorisierung Ihrer App zurückkehren sollen. Dies ist /callback
im 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)
Verwenden Sie das Flow-Objekt, um authorization_url
und state
zu erstellen. Speichern Sie die state
in der Sitzung. Sie wird später verwendet, um die Authentizität der Serverantwort zu bestätigen. Leite den Nutzer schließlich zu 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 Flow-Objekt zu instanziieren und dann die Autorisierungs-URL abzurufen:
- Die Methode
getClientSecrets()
liest die Clientschlüsseldatei und erstellt einGoogleClientSecrets
-Objekt. - Mit der Methode
getFlow()
wird eine Instanz vonGoogleAuthorizationCodeFlow
erstellt. - Die Methode
authorize()
verwendet dasGoogleAuthorizationCodeFlow
-Objekt, den Parameterstate
und den Weiterleitungs-URI, um die Autorisierungs-URL abzurufen. Der Parameterstate
wird verwendet, um die Authentizität der Antwort vom Autorisierungsserver zu überprüfen. Die Methode gibt dann eine Zuordnung 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 Constructor 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. Der Endpunkt speichert dann den Parameter state
in der Sitzung und leitet 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 zur redirect_uri
-Route aus dem vorherigen Schritt zurück. Im obigen Beispiel ist das /callback
.
Sie erhalten ein code
in der Antwort, wenn der Nutzer von der Autorisierungsseite zurückkehrt. Tauschen Sie 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
, aber verwenden Sie dieses Mal den im vorherigen Schritt gespeicherten Status wieder.
@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 enthält das flow
-Objekt auch die Methode fetch_token
, um dies zu erreichen. Für die Methode sind entweder die Argumente code
oder authorization_response
erforderlich. Verwenden Sie 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 in anderen Methoden oder Routen abgerufen werden können, und leiten 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 aus der Weiterleitung abgerufen wurde, die von der Autorisierungs-URL ausgeführt wird. Dieses Credentials
-Objekt wird später verwendet, um das Zugriffstoken und das 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 den Weiterleitungs-URI hinzu. Rufen Sie 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 der Autorisierung fort. Wenn sie nicht übereinstimmen, gib einen Fehler zurück.
Rufen Sie dann die Methode AuthService
getAndSaveCredentials
auf und übergeben Sie den Autorisierungscode als Parameter. Nachdem Sie das Credentials
-Objekt abgerufen haben, speichern Sie es in der Sitzung. Schließen Sie dann das Dialogfeld und leiten Sie den Nutzer zur Add-on-Landingpage 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 Sie den Ablauf abgeschlossen haben, können Sie jetzt Google APIs aufrufen.
Fordern Sie beispielsweise die Profilinformationen des Nutzers an. Sie können die Informationen des Nutzers über die OAuth 2.0 API anfordern.
Python
Lesen Sie die Dokumentation zur OAuth 2.0 Discovery API. Verwenden Sie 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
Erstellen Sie 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 den /test
-Endpunkt dem Controller hinzu, der die E‑Mail-Adresse des Nutzers anzeigt.
/** 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 ihn aus der aktuellen Sitzung entfernen. So können Sie das Routing auf der Add-on-Landingpage testen.
Wir empfehlen, dem Nutzer anzuzeigen, dass er abgemeldet wurde, 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 flask.session.clear()
verwenden. Das kann jedoch unerwünschte Auswirkungen haben, 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);
}
}
App-Berechtigung widerrufen
Ein Nutzer kann die Berechtigung Ihrer App widerrufen, indem er eine POST
-Anfrage an https://oauth2.googleapis.com/revoke
sendet. Die Anfrage sollte 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 Endpunkt „revoke“ 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 löscht 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 Textbereich auf die Schaltfläche Add-ons und wählen Sie dann das gewünschte Add-on aus. Das iFrame wird geöffnet und das Add-on lädt den Attachment Setup URI (URI für die Einrichtung von Anhängen), den Sie im GWM SDK auf der Seite App-Konfiguration angegeben haben.
Glückwunsch! Sie können mit dem nächsten Schritt fortfahren: Wiederholte Besuche Ihres Add-ons verarbeiten.