Tekrarlanan girişleri yönetme

Bu, Classroom eklentilerindeki üçüncü adım adım açıklamalı kılavuzdur. size yol gösterir.

Bu adım adım açıklamalı kılavuzda, eklentimize yapılan yinelenen ziyaretleri otomatik olarak Kullanıcının önceden verilmiş kimlik bilgilerini alma. Ardından kullanıcıları Anında API istekleri gönderebilecekleri sayfalar. Bu, bilgi girilmesi zorunludur veya Classroom eklentilerinin davranışını.

Bu adım adım açıklamalı kılavuz kapsamında aşağıdaki işlemleri tamamlayacaksınız:

  • Kullanıcı kimlik bilgilerimiz için kalıcı depolama alanı uygulayın.
  • login_hint eklentisi sorgu parametresini alma ve değerlendirme. Bu, oturum açmış kullanıcının benzersiz Google kimlik numarası.
ziyaret edin.

Tamamladığınızda web uygulamanızda kullanıcıları tam olarak yetkilendirebilir ve Google API'leri

iframe sorgu parametrelerini anlama

Classroom, eklentinizin Ek Kurulumu URI'sini aşağıdaki durumlarda yükler: açılıyor. Sınıf URI'ye çeşitli GET sorgu parametreleri ekler; bunlar arasında bağlamsal bilgiler sağlar. Örneğin, Ek Keşif URI'niz https://example.com/addon, Classroom, iframe'i şununla oluşturur: kaynak URL https://example.com/addon?courseId=XXX&itemId=YYY&itemType=courseWork&addOnToken=ZZZ, burada XXX, YYY ve ZZZ dize kimlikleridir. Bu uzantı için iframe'ler kılavuzuna ayrıntılı bir şekilde açıklayacağım.

Keşif URL'sinin beş olası sorgu parametresi vardır:

  • courseId: Geçerli Classroom dersinin kimliği.
  • itemId: Kullanıcının düzenlediği veya oluşturduğu akış öğesinin kimliği.
  • itemType: Kullanıcının oluşturduğu veya düzenlediği akış öğesinin türü. courseWork, courseWorkMaterial veya announcement.
  • addOnToken: Belirli kullanıcıları yetkilendirmek için kullanılan jeton Classroom eklentisi işlemleri.
  • login_hint: Geçerli kullanıcının Google kimliği.
ziyaret edin.

Bu adım adım açıklamalı kılavuzda login_hint ele alınmaktadır. Kullanıcılar, bu özelliğin sorgu parametresi, eksikse yetkilendirme akışına veya keşif sayfasını ziyaret edin.

Sorgu parametrelerine erişme

Sorgu parametreleri, URI dizesinde web uygulamanıza iletilir. Mağaza bu değerlerden emin olun. bu bilgiler yetkilendirme akışında kullanılır ve kullanıcı hakkındaki bilgileri depolamak ve almak. Bu sorgu parametreleri yalnızca Eklenti ilk açıldığında iletir.

Python

Flask rotalarınızın tanımlarına gidin (mevcutsanız routes.py ). Eklenti açılış rotanızın üst kısmında (sağladığımız örneğimizde /classroom-addon) kullanarak, login_hint sorgu parametresi:

# If the login_hint query parameter is available, we'll store it in the session.
if flask.request.args.get("login_hint"):
    flask.session["login_hint"] = flask.request.args.get("login_hint")

login_hint (varsa) oturumda depolandığından emin olun. Bu bir bu değerleri depolamak için uygun bir yer, bunlar geçicidir ve yeni değerlere sahip olur.

# It's possible that we might return to this route later, in which case the
# parameters will not be passed in. Instead, use the values cached in the
# session.
login_hint = flask.session.get("login_hint")

# If there's still no login_hint query parameter, this must be their first
# time signing in, so send the user to the sign in page.
if login_hint is None:
    return start_auth_flow()

Java

Kumanda sınıfınızda eklenti açılış rotasına gidin (sağlanan örnekte AuthController.java içinde /addon-discovery). Kuyruklu a işareti bu rotanın başlangıcında, login_hint sorgusunu alın ve depolayın parametresinden sonra bir değer girin.

/** Retrieve the login_hint query parameter from the request URL if present. */
String login_hint = request.getParameter("login_hint");

login_hint (varsa) oturumda depolandığından emin olun. Bu bir bu değerleri depolamak için uygun bir yer, bunlar geçicidir ve yeni değerlere sahip olur.

/** If login_hint wasn't sent, use the values in the session. */
if (login_hint == null) {
    login_hint = (String) session.getAttribute("login_hint");
}

/** If the there is still no login_hint, route the user to the authorization
 *  page. */
if (login_hint == null) {
    return startAuthFlow(model);
}

/** If the login_hint query parameter is provided, add it to the session. */
else if (login_hint != null) {
    session.setAttribute("login_hint", login_hint);
}

Sorgu parametrelerini yetkilendirme akışına ekleme

login_hint parametresi, Google'ın kimlik doğrulama sunucularına iletilmelidir de faydalı olabilir. Bu, kimlik doğrulama sürecini kolaylaştırır; uygulamanız CANNOT TRANSLATE kimlik doğrulaması yapmaya çalıştığında sunucu, işlemi basitleştirmek için ipucunu oturum açma formundaki e-posta alanını önceden doldurarak giriş akışını başlatabilirsiniz.

Python

Flask sunucusu dosyanızda (/authorize) yetkilendirme rotasına gidin ) ekleyebilirsiniz. login_hint bağımsız değişkenini flow.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",
    # The user will automatically be selected if we have the login_hint.
    login_hint=flask.session.get("login_hint"),

Java

AuthService.java sınıfında authorize() yöntemine gidin. Ekle Yönteme parametre olarak login_hint ve login_hint ekleyin yetkilendirme URL'si oluşturucu için bağımsız değişken kullanır.

String authUrl = flow
    .newAuthorizationUrl()
    .setState(state)
    .set("login_hint", login_hint)
    .setRedirectUri(REDIRECT_URI)
    .build();

Kullanıcı kimlik bilgileri için kalıcı depolama alanı ekleyin

Eklenti yüklendiğinde sorgu parametresi olarak login_hint alırsanız bu bir kullanıcının bir uygulamadır. Zorlamak yerine önceki kimlik bilgilerini almalısınız tekrar oturum açmalarını isteyebilir.

Ayrıca, yetkilendirme akışı. Bu jetonu kaydedin, erişim jetonu almak için yeniden kullanılmasını istiyorsanız Bu, kısa ömürlü ve Google API'lerini kullanmak için gerekli. Daha önce kaydettiniz ancak bu bilgileri oturum sırasında devamlılık sağlayabilir.

Kullanıcı şemasını tanımlama ve veritabanını kurma

User için veritabanı şeması oluşturun.

Python

Kullanıcı şemasını tanımlama

User aşağıdaki özellikleri içerir:

  • id: Kullanıcının Google kimliği. Bu, login_hint sorgu parametresi.
  • display_name: Kullanıcının adı ve soyadı (ör. "Ali Demir").
  • email: Kullanıcının e-posta adresi.
  • portrait_url: Kullanıcının profil resminin URL'si.
  • refresh_token: Daha önce edinilen yenileme jetonu.
ziyaret edin.

Bu örnekte, Python. Veritabanımızı kolaylaştırmak için flask_sqlalchemy modülünü kullanıyor. üzerine konuşalım.

Veritabanını kurma

Önce veritabanımız için bir dosya konumu belirtin. Sunucunuza gidin (sağladığımız örneğimizde config.py) kullanarak bir yapılandırma dosyası oluşturun ve takip ediliyor.

import os

# Point to a database file in the project root.
DATABASE_FILE_NAME = os.path.join(
    os.path.abspath(os.path.dirname(__file__)), 'data.sqlite')

class Config(object):
    SQLALCHEMY_DATABASE_URI = f"sqlite:///{DATABASE_FILE_NAME}"
    SQLALCHEMY_TRACK_MODIFICATIONS = False

Bu işlem Flask'ı web sitenizle aynı dizindeki data.sqlite dosyasına yönlendirir. main.py dosya

Ardından, modül dizininize gidin ve yeni bir models.py dosyası oluşturun. Sağladığımız örneği uyguluyorsanız bu değer webapp/models.py olur. Ekle User tablosunu tanımlamak için aşağıdaki kodu yeni dosyaya ekleyin: farklıysa webapp için modül adı.

from webapp import db

# Database model to represent a user.
class User(db.Model):
    # The user's identifying information:
    id = db.Column(db.String(120), primary_key=True)
    display_name = db.Column(db.String(80))
    email = db.Column(db.String(120), unique=True)
    portrait_url = db.Column(db.Text())

    # The user's refresh token, which will be used to obtain an access token.
    # Note that refresh tokens will become invalid if:
    # - The refresh token has not been used for six months.
    # - The user revokes your app's access permissions.
    # - The user changes passwords.
    # - The user belongs to a Google Cloud organization
    #   that has session control policies in effect.
    refresh_token = db.Column(db.Text())

Son olarak, modülünüzün __init__.py dosyasına içe aktarmak için aşağıdakileri ekleyin ve veritabanını oluşturuyoruz.

from webapp import models
from os import path
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

# Initialize the database file if not created.
if not path.exists(config.DATABASE_FILE_NAME):
    db.create_all()

Java

Kullanıcı şemasını tanımlama

User aşağıdaki özellikleri içerir:

  • id: Kullanıcının Google kimliği. Bu, login_hint sorgu parametresi.
  • email: Kullanıcının e-posta adresi.
ziyaret edin.

Modülün resources dizininde bir schema.sql dosyası oluşturun. Yay bu dosyayı okur ve buna göre veritabanı için bir şema oluşturur. Tabloyu bir tablo adı, users ve temsil edilecek sütunlarla tanımlayın User özellikleri, id ve email.

CREATE TABLE IF NOT EXISTS users (
    id VARCHAR(255) PRIMARY KEY, -- user's unique Google ID
    email VARCHAR(255), -- user's email address
);

Veritabanında User modelini tanımlamak için bir Java sınıfı oluşturun. Bu User.java olarak tanımlanmıştır.

Bunun bir POJO olduğunu belirtmek için @Entity ek açıklamasını ekleyin. kaydedilir. @Table ek açıklamasını (schema.sql) yapılandırdığınız ilgili tablo adını girin.

Kod örneğin, iki öğe için oluşturucu ve belirleyicileri özellikleri hakkında daha fazla bilgi edinin. Oluşturucu ve belirleyiciler, Veritabanında kullanıcı oluşturmak veya güncellemek için AuthController.java. Siz uygun gördüğünüz şekilde alıcıları ve toString yöntemini de içerebilir, ancak bu özel çözümden yararlandığınızda, bu yöntemler kullanılmaz ve bu sayfadaki kod örneğine göz atın.

/** An entity class that provides a model to store user information. */
@Entity
@Table(name = "users")
public class User {
    /** The user's unique Google ID. The @Id annotation specifies that this
     *   is the primary key. */
    @Id
    @Column
    private String id;

    /** The user's email address. */
    @Column
    private String email;

    /** Required User class no args constructor. */
    public User() {
    }

    /** The User class constructor that creates a User object with the
    *   specified parameters.
    *   @param id the user's unique Google ID
    *   @param email the user's email address
    */
    public User(String id, String email) {
        this.id = id;
        this.email = email;
    }

    public void setId(String id) { this.id = id; }

    public void setEmail(String email) { this.email = email; }
}

CRUD işlemlerini yönetmek için UserRepository.java adlı bir arayüz oluşturun ekler. Bu arayüz, CrudRepository arayüzünü genişletir.

/** Provides CRUD operations for the User class by extending the
 *   CrudRepository interface. */
@Repository
public interface UserRepository extends CrudRepository<User, String> {
}

Denetleyici sınıfı, istemci ile istemci arasındaki iletişimi kolaylaştırır. depodur. Bu nedenle, denetleyici sınıf oluşturucusunu UserRepository sınıfı.

/** Declare UserRepository to be used in the Controller class constructor. */
private final UserRepository userRepository;

/**
*   ...
*   @param userRepository the class that interacts with User objects stored in
*   persistent storage.
*/
public AuthController(AuthService authService, UserRepository userRepository) {
    this.authService = authService;
    this.userRepository = userRepository;
}

Veritabanını kurma

Kullanıcıyla ilgili bilgileri depolamak için, yapısı gereği olduğu için özel bir H2 veritabanı Spring Boot tarafından desteklenir. Bu veritabanı, sonraki işlemlerde de kullanılır Classroom'la ilgili diğer bilgileri depolamak için adım adım açıklamalı kılavuzlar ekleyebilirsiniz. H2 veritabanını kurmak için şunların eklenmesi gerekir: application.properties öğesine yükleyin.

# Enable configuration for persistent storage using an H2 database
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:file:./h2/userdb
spring.datasource.username=<USERNAME>
spring.datasource.password=<PASSWORD>
spring.jpa.hibernate.ddl-auto=update
spring.jpa.open-in-view=false

spring.datasource.url yapılandırması, h2 adında bir dizin oluşturur ve userdb adlı bir dosyadır. H2 veritabanına giden yolu .gitignore. spring.datasource.username ve ayarlamak için uygulamayı çalıştırmadan spring.datasource.password önce oluşturduğunuz kullanıcı adını ve şifreyi girin. Güncellemek için kullanıcı adınızı ve şifrenizi girin. oluşturulan h2 dizinini silin, yapılandırmayı güncelleyin ve yeniden çalıştırın.

spring.jpa.hibernate.ddl-auto yapılandırmasını update olarak ayarlamak şunları sağlar: Uygulama yeniden başlatıldığında, veritabanında depolanan veriler korunur. Uygulama her yeniden başlatıldığında veritabanını temizlemek için bu create öğesine yapılandırın.

spring.jpa.open-in-view yapılandırmasını false olarak ayarlayın. Bu yapılandırma etkinleştirildi ve RACI matrisleri gibi performans sorunlarına üretimde teşhis edilmesi zordur.

Daha önce açıklandığı gibi, bir sitenin kimlik bilgilerini almak için tekrarlayan bir kullanıcıdır. Bu işlem, yerleşik kimlik bilgisi deposu tarafından sağlanır desteği GoogleAuthorizationCodeFlow tarafından sunulmaktadır.

AuthService.java sınıfında, kimlik bilgisi sınıfı depolanır. Bu örnekte, dosya /credentialStore dizini. Kimlik bilgileri deposunun yolunu .gitignore Bu dizin, kullanıcı yetkilendirme akışı.

private static final File dataDirectory = new File("credentialStore");

Sonra, AuthService.java dosyasında FileDataStoreFactory nesnesini döndürür. Bu, projenin yürütülmesi sırasında kimlik bilgilerini saklar.

/** Creates and returns FileDataStoreFactory object to store credentials.
 *   @return FileDataStoreFactory dataStore used to save and obtain users ids
 *   mapped to Credentials.
 *   @throws IOException if creating the dataStore is unsuccessful.
 */
public FileDataStoreFactory getCredentialDataStore() throws IOException {
    FileDataStoreFactory dataStore = new FileDataStoreFactory(dataDirectory);
    return dataStore;
}

AuthService.java uygulamasında getFlow() yöntemini güncelleyerek GoogleAuthorizationCodeFlow Builder() içinde setDataStoreFactory yöntemini çağırın ve veri deposunu ayarlamak için getCredentialDataStore() yöntemini çağırın.

GoogleAuthorizationCodeFlow authorizationCodeFlow =
    new GoogleAuthorizationCodeFlow.Builder(
        HTTP_TRANSPORT,
        JSON_FACTORY,
        getClientSecrets(),
        getScopes())
    .setAccessType("offline")
    .setDataStoreFactory(getCredentialDataStore())
    .build();

Sonra, getAndSaveCredentials(String authorizationCode) yöntemini güncelleyin. Daha önce bu yöntem, kimlik bilgilerini depolamadan alıyordu elinizin altında. Kimlik bilgilerini veri deposunda depolamak için yöntemi güncelleyin kullanıcı kimliği tarafından dizine eklendi.

User ID, TokenResponse nesnesinden şu kullanılarak elde edilebilir: id_token ancak önce doğrulanması gerekir. Aksi halde, uygulamalar, değiştirilmiş bir kullanıcı göndererek kullanıcıların kimliğine bürünebilir kimlikleri sunucuya gönderilir. Google API İstemcisini kullanmanız önerilir: kütüphanelerini kullanarak id_token test edin. [Google Kimliği sayfası] Google kimlik jetonunu doğrulayın].

// Obtaining the id_token will help determine which user signed in to the application.
String idTokenString = tokenResponse.get("id_token").toString();

// Validate the id_token using the GoogleIdTokenVerifier object.
GoogleIdTokenVerifier googleIdTokenVerifier = new GoogleIdTokenVerifier.Builder(
        HTTP_TRANSPORT,
        JSON_FACTORY)
    .setAudience(Collections.singletonList(
        googleClientSecrets.getWeb().getClientId()))
    .build();

GoogleIdToken idToken = googleIdTokenVerifier.verify(idTokenString);

if (idToken == null) {
    throw new Exception("Invalid ID token.");
}

id_token doğrulandıktan sonra, birlikte depolamak için userId alın bu belgelere güvenebilirsiniz.

// Obtain the user id from the id_token.
Payload payload = idToken.getPayload();
String userId = payload.getSubject();

Çağrıyı, userId içerecek şekilde flow.createAndStoreCredential olarak güncelleyin.

// Save the user id and credentials to the configured FileDataStoreFactory.
Credential credential = flow.createAndStoreCredential(tokenResponse, userId);

AuthService.java sınıfına, kimlik bilgilerini döndüren bir yöntem ekleyin veri deposunda bulunuyorsa belirli bir kullanıcı için.

/** Find credentials in the datastore based on a specific user id.
*   @param userId key to find in the file datastore.
*   @return Credential object to be returned if a matching key is found in the datastore. Null if
*   the key doesn't exist.
*   @throws Exception if building flow object or checking for userId key is unsuccessful. */
public Credential loadFromCredentialDataStore(String userId) throws Exception {
    try {
        GoogleAuthorizationCodeFlow flow = getFlow();
        Credential credential = flow.loadCredential(userId);
        return credential;
    } catch (Exception e) {
        e.printStackTrace();
        throw e;
    }
}

Kimlik bilgilerini alma

Users öğesini getirmek için bir yöntem tanımlayın. Şurada bir id sağlanmıştır: Belirli bir kullanıcıyı almak için kullanabileceğiniz login_hint sorgu parametresi kullanabilirsiniz.

Python

def get_credentials_from_storage(id):
    """
    Retrieves credentials from the storage and returns them as a dictionary.
    """
    return User.query.get(id)

Java

AuthController.java sınıfında, şuradan kullanıcı almak için bir yöntem tanımlayın: kullanıcı kimliğine göre veritabanını kullanarak düzenleyebilir.

/** Retrieves stored credentials based on the user id.
*   @param id the id of the current user
*   @return User the database entry corresponding to the current user or null
*   if the user doesn't exist in the database.
*/
public User getUser(String id) {
    if (id != null) {
        Optional<User> user = userRepository.findById(id);
        if (user.isPresent()) {
            return user.get();
        }
    }
    return null;
}

Kimlik bilgilerini depola

Kimlik bilgileri depolanırken iki senaryo mevcuttur. Kullanıcının id cihazı zaten seçin ve ardından mevcut kaydı yeni değerlerle güncelleyin. Aksi halde yeni bir User kaydı oluşturun ve bu kaydı veritabanına ekleyin.

Python

Öncelikle depolama veya güncelleme işlemini uygulayan bir yardımcı program yöntemi tanımlayın gösterir.

def save_user_credentials(credentials=None, user_info=None):
    """
    Updates or adds a User to the database. A new user is added only if both
    credentials and user_info are provided.

    Args:
        credentials: An optional Credentials object.
        user_info: An optional dict containing user info returned by the
            OAuth 2.0 API.
    """

    existing_user = get_credentials_from_storage(
        flask.session.get("login_hint"))

    if existing_user:
        if user_info:
            existing_user.id = user_info.get("id")
            existing_user.display_name = user_info.get("name")
            existing_user.email = user_info.get("email")
            existing_user.portrait_url = user_info.get("picture")

        if credentials and credentials.refresh_token is not None:
            existing_user.refresh_token = credentials.refresh_token

    elif credentials and user_info:
        new_user = User(id=user_info.get("id"),
                        display_name=user_info.get("name"),
                        email=user_info.get("email"),
                        portrait_url=user_info.get("picture"),
                        refresh_token=credentials.refresh_token)

        db.session.add(new_user)

    db.session.commit()

Kimlik bilgilerini iki farklı şekilde veritabanı: kullanıcı, projenizin sonunda uygulamanıza geri döndüğünde yetkilendirme akışı ve API çağrısı yayınlama zamanları. İşte bu noktada daha önce oturum credentials anahtarını ayarladı.

callback rotanızın sonunda save_user_credentials numaralı telefonu arayın. Şunu sakla: user_info nesnesini oluşturmanıza yardımcı olur.

# The flow is complete! We'll use the credentials to fetch the user's info.
user_info_service = googleapiclient.discovery.build(
    serviceName="oauth2", version="v2", credentials=credentials)

user_info = user_info_service.userinfo().get().execute()

flask.session["username"] = user_info.get("name")

save_user_credentials(credentials, user_info)

Ayrıca, API'ye yapılan çağrıların ardından kimlik bilgilerini de güncellemeniz gerekir. Burada Bu durumda, güncellenen kimlik bilgilerini save_user_credentials yöntemini çağırın.

# Save credentials in case access token was refreshed.
flask.session["credentials"] = credentials_to_dict(credentials)
save_user_credentials(credentials)

Java

Öncelikle H2'de User nesnesini depolayan veya güncelleyen bir yöntem tanımlayın

/** Adds or updates a user in the database.
*   @param credential the credentials object to save or update in the database.
*   @param userinfo the userinfo object to save or update in the database.
*   @param session the current session.
*/
public void saveUser(Credential credential, Userinfo userinfo, HttpSession session) {
    User storedUser = null;
    if (session != null && session.getAttribute("login_hint") != null) {
        storedUser = getUser(session.getAttribute("login_hint").toString());
    }

    if (storedUser != null) {
        if (userinfo != null) {
            storedUser.setId(userinfo.getId());
            storedUser.setEmail(userinfo.getEmail());
        }
        userRepository.save(storedUser);
    } else if (credential != null && userinfo != null) {
        User newUser = new User(
            userinfo.getId(),
            userinfo.getEmail(),
        );
        userRepository.save(newUser);
    }
}

Kimlik bilgilerini iki farklı şekilde veritabanı: kullanıcı, projenizin sonunda uygulamanıza geri döndüğünde yetkilendirme akışı ve API çağrısı yayınlama zamanları. İşte bu noktada daha önce oturum credentials anahtarını ayarladı.

/callback rotasının sonunda saveUser numaralı telefonu arayın. Lütfen user_info nesnesini oluşturmanıza yardımcı olur.

/** This is the end of the auth flow. We should save user info to the database. */
Userinfo userinfo = authService.getUserInfo(credentials);
saveUser(credentials, userinfo, session);

Ayrıca, API'ye yapılan çağrıların ardından kimlik bilgilerini de güncellemeniz gerekir. Burada Bu durumda, güncellenen kimlik bilgilerini saveUser öğesine bağımsız değişken olarak sağlayabilirsiniz. yöntemidir.

/** Save credentials in case access token was refreshed. */
saveUser(credentials, null, session);

Süresi dolmuş kimlik bilgileri

Yenileme jetonlarının geçersiz hale gelmesinin birkaç nedeni olabileceğini unutmayın. Bu şunlardır:

  • Yenileme jetonu altı aydır kullanılmamış.
  • Kullanıcı, uygulamanızın erişim izinlerini iptal ederse.
  • Kullanıcı şifreleri değiştirir.
  • Kullanıcı, oturum denetimi olan bir Google Cloud kuruluşuna ait yürürlükte.

Aşağıdaki durumlarda kullanıcıyı yetkilendirme akışı üzerinden tekrar göndererek yeni jetonlar edinin: kimlik bilgileri geçersiz hale gelir.

Kullanıcıyı otomatik olarak yönlendir

Kullanıcının daha önce izin verip vermediğini algılamak için eklenti açılış rotasını değiştirme oluşturmak istiyoruz. Bu durumda, bunları ana eklenti sayfamıza yönlendirin. Aksi takdirde, bu bilgilerden yararlanabilirsiniz.

Python

Uygulama lansman sonrasında gerçekleşebilir. Aşağıdakini bir modül başlatıcıya (örneğin, webapp/__init__.py) veya ana yöntemde sunucuyu başlatır.

# Initialize the database file if not created.
if not os.path.exists(DATABASE_FILE_NAME):
    db.create_all()

Bu durumda yönteminiz, login_hint sorgu parametresini yukarıda açıklanmıştır. Daha sonra, bu tekrarlanıyorsa mağaza kimlik bilgilerini yükleyin ziyaret eder. login_hint gelen kullanıcının tekrar gelen bir ziyaretçi olduğunu anlarsınız. Bu kullanıcı için depolanmış kimlik bilgilerini alın ve kabul edilir.

stored_credentials = get_credentials_from_storage(login_hint)

# If we have stored credentials, store them in the session.
if stored_credentials:
    # Load the client secrets file contents.
    client_secrets_dict = json.load(
        open(CLIENT_SECRETS_FILE)).get("web")

    # Update the credentials in the session.
    if not flask.session.get("credentials"):
        flask.session["credentials"] = {}

    flask.session["credentials"] = {
        "token": stored_credentials.access_token,
        "refresh_token": stored_credentials.refresh_token,
        "token_uri": client_secrets_dict["token_uri"],
        "client_id": client_secrets_dict["client_id"],
        "client_secret": client_secrets_dict["client_secret"],
        "scopes": SCOPES
    }

    # Set the username in the session.
    flask.session["username"] = stored_credentials.display_name

Son olarak, kimlik bilgileri. Bu durumda, bunları ana eklenti sayfasına yönlendirin.

if "credentials" not in flask.session or \
    flask.session["credentials"]["refresh_token"] is None:
    return flask.render_template("authorization.html")

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

Java

Eklentinizin açılış rotasına (/addon-discovery sağlanan örneğine bakın). Yukarıda açıklandığı gibi, login_hint konusunu burada ele aldınız. sorgu parametresidir.

Öncelikle oturumda kimlik bilgilerinin olup olmadığını kontrol edin. Aksi takdirde startAuthFlow yöntemini çağırarak yetkilendirme akışı sırasında kullanıcıyı doğrulamanız gerekir.

/** Check if the credentials exist in the session. The session could have
 *   been cleared when the user clicked the Sign-Out button, and the expected
 *   behavior after sign-out would be to display the sign-in page when the
 *   iframe is opened again. */
if (session.getAttribute("credentials") == null) {
    return startAuthFlow(model);
}

Ardından, bu tekrar gelen bir ziyaretçiyse H2 veritabanından kullanıcıyı yükleyin. İnsanların login_hint sorgu parametresini alırsanız tekrar gelen ziyaretçiniz olur. Öğe H2 veritabanında varsa kimlik bilgilerini kimlik bilgisi daha önce ayarladığınız ve kimlik bilgilerini oturumda ayarlayın. Öğe kimlik bilgileri, kimlik bilgisi veri deposundan alınamadı, kullanıcıyı yönlendir startAuthFlow numaralı telefonu arayarak yetkilendirme akışı sürecini tamamlayın.

/** At this point, we know that credentials exist in the session, but we
 *   should update the session credentials with the credentials in persistent
 *   storage in case they were refreshed. If the credentials in persistent
 *   storage are null, we should navigate the user to the authorization flow
 *   to obtain persisted credentials. */

User storedUser = getUser(login_hint);

if (storedUser != null) {
    Credential credential = authService.loadFromCredentialDataStore(login_hint);
    if (credential != null) {
        session.setAttribute("credentials", credential);
    } else {
        return startAuthFlow(model);
    }
}

Son olarak, kullanıcıyı eklenti açılış sayfasına yönlendirin.

/** Finally, if there are credentials in the session and in persistent
 *   storage, direct the user to the addon-discovery page. */
return "addon-discovery";

Eklentiyi test etme

Google Classroom'da Öğretmen testinizden biri olarak oturum açın yardımcı olur. Sınıf Çalışmaları sekmesine gidin ve yeni bir Ödev oluşturun. Sonraki slayta geçin Metin alanının altındaki Eklentiler düğmesini tıklayın ve ardından eklentinizi seçin. iframe açılır ve eklenti, Google Etiket Yöneticisi'nde belirttiğiniz Ek Kurulum URI'si Google Workspace Marketplace SDK'sının Uygulama Yapılandırması sayfası

Tebrikler! Sonraki adıma geçmeye hazırsınız: Ek oluşturma ve kullanıcının rolünün tanımlanması.