Integracja po stronie serwera

Do zarządzania czytelników i ich uprawnieniami wydawcy używają głównie integracji po stronie serwera. Głównie wydawcy używają parametru UpdateReaderEntitlements do aktualizowania w Google rekordu dotyczącego identyfikatora produktu, który jest używany w przypadku identyfikatora PPID.

Konfiguracja Google Cloud

Konfigurowanie łączenia subskrypcji w Google Cloud składa się z 2 głównych komponentów:

  1. Włączanie interfejsu API w danym projekcie
  2. Tworzę konto usługi umożliwiające dostęp do interfejsu API

Włącz interfejs Subscription Linking API

Aby móc używać konta usługi i zarządzać uprawnieniami czytelników, projekt Google Cloud musi mieć włączony interfejs Subscription Linking API oraz prawidłowo skonfigurowane konto usługi OAuth. Aby włączyć w projekcie interfejs Subscription Linking API, wybierz kolejno menu -> APIs & Services -> Library (Interfejsy API i usługi) -> Library (Biblioteka) i wyszukaj pozycję Subscription Linking lub bezpośrednio otwórz stronę:


https://console.cloud.google.com/apis/library?project=gcp_project_id

api

Rysunek 1. Przejście do biblioteki interfejsów API i włączenie interfejsu API w projekcie Google Cloud.

Utwórz konto usługi

Konta usługi umożliwiają aplikacji dostęp do interfejsu Subscription Linking API.

  1. Utwórz konto usługi w konsoli projektu.
  2. Utwórz dane logowania dla konta usługi i zapisz plik credentials.json w bezpiecznej lokalizacji dostępnej dla aplikacji.
  3. Przypisz rolę uprawnień „Administrator połączeń subskrypcji” do utworzonego konta usługi. Aby mieć większą kontrolę nad możliwościami konta usługi, możesz przypisać odpowiednią rolę z tabeli poniżej.
Kompetencje / rola Administrator połączeń subskrypcji Wyświetlający połączenia subskrypcji Wyświetlający uprawnienia połączeń subskrypcji
Pobieranie uprawnień czytelników
Pozyskiwanie czytelników
Aktualizowanie uprawnień czytelników
Usuń czytelników

Używanie kont usługi z interfejsem Subscription Linking API

Konta usługi umożliwiają uwierzytelnianie wywołań interfejsu Subscription Linking API za pomocą biblioteki klienta googleapis lub poprzez podpisywanie żądań za pomocą interfejsu API REST. Biblioteki klienta automatycznie obsługują żądania odpowiedniego access_token, natomiast interfejs API REST wymaga pobrania id_token, a następnie wymiany go na access_token.

Zarówno poniższe przykłady biblioteki klienta, jak i przykłady interfejsu API REST używają punktu końcowego getReader(). Prezentację na żywo wszystkich metod interfejsu API znajdziesz w witrynie prezentacji funkcji łączenia subskrypcji lub jej kodzie.

Przykładowe żądanie z biblioteką klienta node.js googleapis

import {readerrevenuesubscriptionlinking_v1, Auth} from 'googleapis'
const subscriptionLinking = readerrevenuesubscriptionlinking_v1.Readerrevenuesubscriptionlinking

class SubscriptionLinking {
  constructor() {
    this.auth = new Auth.GoogleAuth({
      keyFile: process.env.KEY_FILE,
      scopes: [
        'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage'
      ],
    })
  }

  init() {
    return new subscriptionLinking(
        {version: 'v1', auth: this.auth})
  }
}

const api = new SubscriptionLinking()
const client = api.init()

async function getReader (ppid) {
  const publicationId = process.env.PUBLICATION_ID
  return await client.publications.readers.get({
    name: `publications/${publicationId}/readers/${ppid}`,
  })
}

Ręczne podpisywanie żądań do interfejsu API REST

import fetch from 'node-fetch'
import jwt from 'jsonwebtoken'

function getSignedJwt() {
  /*
    Either store the credentials string in an environmental variable
    Or implement logic to fetch it.
  */
  const key_file = process.env.CREDENTIALS_STRING

  const issueDate = new Date()
  const expireMinutes = 60
  const offsetInSeconds = issueDate.getTimezoneOffset() * 60000
  const expireDate = new Date(issueDate.getTime() + (expireMinutes * 60000))
  const iat = Math.floor((issueDate.getTime() + offsetInSeconds) / 1000)
  const exp = Math.floor((expireDate.getTime() + offsetInSeconds) / 1000)

  const token = {
    iss: key_file.client_email,
    iat,
    exp,
    aud: 'https://oauth2.googleapis.com/token',
    scope:'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage',
  }
  return jwt.sign(token, key_file.private_key, {
    algorithm: 'RS256',
    keyid: key_file.private_key_id,
  })
}

async function getAccessToken(signedJwt) {
  let body = new URLSearchParams();
  body.set('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer')
  body.set('assertion', signedJwt)
  const request = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    body
  })

  const accessResponse = await accessFetch.json()
  return accessResponse.access_token
}

async function getReader(ppid) {
  const publicationId = process.env.PUBLICATION_ID
  const base_url = 'https://readerrevenuesubscriptionlinking.googleapis.com/v1'
  const endpoint = `${base_url}/publications/${publicationId}/readers/${ppid}`
  const signedJwt = await getSignedJwt()
  const accessToken = await getAccessToken(signedJwt)

  const reader = await fetch(endpoint, {
     method: 'GET',
     headers: {
       Authorization: `Bearer ${accessToken}`,
     },
   }).then((response) => {
    return response.json()
  })

  return reader
}