Kehittäjille

Liitä järjestelmäsi Membershipiin ja tarkista, kuka on organisaation jäsen ilman, että jäsentietoja tarvitsee kopioida omaan tietokantaasi.

Yleiskuva

Organisaatiot hallitsevat jäsenistöään Membershipissä. Muut järjestelmät tarvitsevat usein tiedon siitä, onko henkilö tällä hetkellä jäsen: kilpailujärjestelmä ilmoittautumisen hintaa varten, varausjärjestelmä kulkuoikeuksia varten ja harjoituspäiväkirja osallistumisoikeuden tarkistamiseen. Connections-rajapinta vastaa nimenomaan tähän kysymykseen eikä mihinkään muuhun.

Organisaation ylläpitäjä antaa järjestelmällesi luvan kertaalleen, ja sen jälkeen voit:

  • lukea yhdistetyn organisaation julkiset perustiedot (nimi, tunnus, jäsenmäärä)
  • kysyä, kuuluuko tietty sähköpostiosoite organisaation nykyiselle jäsenelle
  • lukea jäsenen jäsenlajin ja sen, onko kuluvan kauden jäsenmaksu hoidettu

Rajapinta on toistaiseksi vain lukeva ja rajattu aina yhteen organisaatioon. Se ei koskaan palauta nimiä, osoitteita, puhelinnumeroita tai maksusummia, eikä sillä voi tehdä muutoksia Membershipiin.

Jos haluat, että jäsen kirjautuu palveluusi itse ja kertoo samalla, kuka hän on, käytä Connections-rajapinnan sijaan Kirjaudu Membershipillä -kirjautumista. Silloin jäsen hyväksyy tietojensa jakamisen itse, ja palvelusi saa hänen nimensä, sähköpostiosoitteensa ja jäsenyytensä tiedot suoraan häneltä.

Miten parittaminen toimii

Parittaminen on suunniteltu siten, ettei pitkäaikainen salaisuus kulje koskaan selaimen, sähköpostin tai pikaviestimen kautta. Ylläpitäjä käsittelee vain lyhytikäistä tunnusta, ja varsinainen API-avain vaihdetaan oman palvelimesi ja palvelimemme välillä.

  1. Organisaation omistaja tai ylläpitäjä avaa organisaation asetukset Membershipissä ja luo paritustunnuksen. Se on muodossa ABCD-EFGH, voimassa 15 minuuttia ja käytettävissä kertaalleen.
  2. Ylläpitäjä syöttää tunnuksen järjestelmäsi integraatioasetuksiin.
  3. Palvelimesi (ei selainsovelluksesi) kutsuu POST /ext/connections/claim ja ilmoittaa samalla, mikä järjestelmä on kyseessä ja mihin kohteeseen se liitetään.
  4. Membership tarkistaa tunnuksen, luo yhteyden ja palauttaa API-avaimen sekä organisaation perustiedot. Avain näytetään vain tämän yhden kerran.
  5. Tallennat avaimen salattuna ja käytät sitä kaikissa myöhemmissä kutsuissa. Ylläpitäjä näkee järjestelmäsi organisaation yhteyslistassa ja voi poistaa yhteyden milloin tahansa.

Koska ylläpitäjä luo tunnuksen Membershipissä, voimassa olevan tunnuksen hallussapito osoittaa, että yhteyden muodostavalla henkilöllä on todella oikeus hallinnoida organisaatiota. Järjestelmäsi ei koskaan kysy käyttäjältä Membershipin kirjautumistietoja, eikä Membership puolestaan käsittele käyttäjiesi salasanoja.

Osoite ja tunnistautuminen

Kaikki rajapintapäätepisteet sijaitsevat osoitteessa https://api.membership.fi/api/v1. Lähetä API-avain Bearer-tunnisteena jokaisessa kutsussa parituskutsua lukuun ottamatta:

Authorization: Bearer mepk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

Avaimet alkavat etuliitteellä mepk_, sisältävät 256 bittiä satunnaisuutta ja ovat rajattuja aina yhteen organisaatioon sekä yhteen liitettyyn kohteeseen. Kyseessä on palvelinten välinen rajapinta: selainkutsut estetään CORS-säännöillä, ja avaimen välittäminen selaimeen antaisi kenelle tahansa suoran lukuoikeuden organisaation jäsenyystietoihin. Säilytä avainta siis aina suojattuna omalla palvelimellasi.

Päätepisteet

Rajapinta kuvaa itse itsensä. Kaikki alla esitetty tieto luetaan suoraan osoitteesta /api/v1/openapi.json. Se on OpenAPI 3.1 -kuvaus, joka muodostetaan samoista skeemoista, joilla rajapinta validoi saapuvat pyynnöt. Dokumentaation lukeminen ei vaadi avainta, ja voit osoittaa asiakasgeneraattorin suoraan siihen.

Koska kuvaus syntyy suoraan sopimusta valvovasta koodista eikä erillisestä käsin ylläpidettävästä sivusta, se ei voi sisältää vanhentunutta tietoa päätepisteistä.

Reading the API description...

Vastaukset ja virheet

Jokainen JSON-vastaus on kuoritettu. Onnistuneet kutsut palauttavat { "success": true, "data": ... } ja virheet { "success": false, "error": { "code", "message" } }.

TilaMerkitysMitä tehdä
400Virheellinen paritustunnus tai kenttä ei läpäissyt tarkistustaPyydä uusi tunnus tai korjaa pyyntö. Älä yritä uudelleen samoilla tiedoilla.
401Avain puuttuu, on tuntematon, vaihdettu tai mitätöityLopeta kutsut, merkitse yhteys korjausta vaativaksi ja pyydä uutta paritustunnusta.
429Kutsurajoitus ylittyiHidasta kutsuväliä ja yritä myöhemmin uudelleen. Tallenna tulokset välimuistiin turhien kutsujen välttämiseksi.
5xxMembership ei ole käytettävissäYritä uudelleen porrastetusti ja tukeudu järjestelmäsi varasuunnitelmaan. Älä jätä käyttäjää odottamaan vastausta loputtomiin.

Avaimen elinkaari

Avain lakkaa toimimasta kahdesta syystä, ja molemmat näkyvät HTTP 401 -virheenä:

  • Uudelleenparitus. Uuden tunnuksen lunastaminen samalla systemKey- ja externalId-yhdistelmällä korvaa aiemman yhteyden avaimen uudella. Edellinen avain lakkaa toimimasta välittömästi, joten uudelleenparitus ei jätä taustalle vanhoja toimivia avaimia. Tämä on suositeltu tapa korjata vikaantunut yhteys.
  • Mitätöinti. Organisaation ylläpitäjä voi poistaa käyttöoikeutesi asetuksistaan milloin tahansa, ja voit mitätöidä oman avaimesi kutsulla DELETE /ext/connection.

Käsittele HTTP 401 normaalina tilanteena sovelluksen kaatumisen sijaan. Kerro käyttäjälle, että yhteys on muodostettava uudelleen, ja ohjeista toimenpiteet selkeästi. Älä jatka kutsujen tekemistä mitätöidyllä avaimella, sillä toistuvat virheet kuluttavat vain tarpeettomasti kutsurajaa.

Toteutuksen tarkistuslista

  • Lunasta tunnukset ja tallenna avaimet vain omalla palvelimellasi. Älä koskaan välitä avainta selaimeen tai mobiilisovellukseen.
  • Salaa avaimet tallennusvaiheessa ja pidä ne poissa lokeista, virheraporteista sekä rajapintavastauksista.
  • Rajaa parituksen ja sen purkamisen oikeus liitettävän kohteen ylläpitäjiin.
  • Käytä pysyvää systemKey-tunnistetta ja lähetä externalUrl, jotta ylläpito näkee, mihin lupa annettiin.
  • Lähetä vain sellaisen henkilön sähköpostiosoite, joka todella asioi kyseisessä kohteessa. Tämä rajapinta ei ole tarkoitettu satunnaisten osoitteiden massahakuihin.
  • Tallenna tarkistusten tulokset välimuistiin lyhyeksi ajaksi (esimerkiksi muutamasta minuutista muutamaan tuntiin) sen sijaan, että tekisit uuden kutsun jokaisella sivulatauksella.
  • Valitse ja dokumentoi toimintatapa niitä tilanteita varten, joissa Membership ei ole tavoitettavissa: voit joko päästää pyynnön läpi käsittelemällä henkilön ei-jäsenenä tai estää pääsyn, mutta älä jätä ratkaisua sattuman varaan.
  • Kutsu DELETE /ext/connection, kun käyttäjä katkaisee yhteyden, ja poista avain.
  • Käsittele 401-tilanne pyytämällä uutta paritustunnusta sen sijaan, että yrittäisit toistaa samaa kutsua.

Tietosuoja

Tarkistus lähettää Membershipille yhden sähköpostiosoitteen ja palauttaa jäsenyystilanteen. Molemmat osapuolet käsittelevät henkilötietoja, joten toteuttajana sinun kannattaa:

  • kertoa käyttäjille tietosuojaselosteessasi, että jäsenyys tarkistetaan Membershipistä, ja perustella miksi
  • tallentaa vain ne tiedot, joita toiminnallisuus välttämättä tarvitsee (yleensä pelkkä totuusarvo ja aikaleima riittävät)
  • pitää yhteys rajattuna siihen kohteeseen, jolle lupa myönnettiin, äläkä käytä yhden organisaation avainta muualla järjestelmässäsi

Organisaatiot toimivat edelleen omien jäsentietojensa rekisterinpitäjinä. Niiden ylläpitäjät näkevät kaikki yhdistetyt järjestelmät sekä niiden viimeisimmän käyttöajankohdan, ja he voivat katkaista yhteyden ilman erillistä yhteydenottoa.

Esimerkki

Paritus kerran, sen jälkeen jäsenyyden tarkistus:

# 1. Lunasta ylläpitäjän antama tunnus (palvelimella)
curl -X POST https://api.membership.fi/api/v1/ext/connections/claim \
  -H 'Content-Type: application/json' \
  -d '{
    "code": "ABCD-EFGH",
    "systemKey": "example-system",
    "systemName": "Example System",
    "externalId": "seura-42",
    "externalName": "Esimerkkiseura",
    "externalUrl": "https://example.com/seurat/esimerkkiseura"
  }'

# 2. Tallenna data.apiKey salattuna ja tarkista jäsenyys
curl -X POST https://api.membership.fi/api/v1/ext/members/verify \
  -H "Authorization: Bearer $MEMBERSHIP_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "email": "henkilo@example.com" }'

Sama TypeScriptillä, virhetilanteet huomioiden:

const BASE_URL = 'https://api.membership.fi/api/v1';

export async function verifyMember(apiKey: string, email: string) {
  const response = await fetch(`${BASE_URL}/ext/members/verify`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email }),
  });

  if (response.status === 401) {
    // Mitätöity tai vaihdettu: pyydä käyttäjää parittamaan uudelleen
    throw new ConnectionNeedsReconnect();
  }
  if (!response.ok) {
    // Ei tavoitettavissa tai kutsuraja ylittyi: käytä varasuunnitelmaa
    throw new MembershipUnavailable(response.status);
  }

  const { data } = await response.json();
  return data; // { isMember, membershipType, memberSince, currentSeason }
}

Kirjaudu Membershipillä (OpenID Connect)

Yhdistyksen verkkosivut ja muut palvelut voivat kirjata jäsenen sisään hänen Membership-tunnuksellaan. Kirjautuminen noudattaa OpenID Connect -standardia, joten mikä tahansa sitä tukeva kirjasto tai lisäosa toimii ilman Membershipille omaa koodia. Palvelu saa tietää, kuka kirjautui, ja hänen jäsenyytensä siinä yhdistyksessä, joka palvelun lisäsi. Salasana ei kulje palvelun kautta, ja jäsen hyväksyy tietojen jakamisen kerran palvelua kohden.

WordPress

WordPress-sivuille on valmis lisäosa, Membership.fi. Se hoitaa kirjautumisen, sivut ja tiedostot vain jäsenille tai valituille ryhmille sekä pääsyn päättymisen, kun jäsenyys päättyy. Päivitykset tulevat membership.fi:stä WordPressin tavallisten päivitysten mukana. Lataa lisäosa ja katso käyttöönotto-ohjeet. Muulla alustalla toimivalle palvelulle alla ovat asetukset, joita mikä tahansa OpenID Connect -kirjasto tarvitsee.

Käyttöönotto

  1. Yhdistyksen ylläpitäjä lisää palvelun Membershipissä kohdassa Asetukset, Yhteydet, Kirjaudu Membershipillä ja antaa sen paluuosoitteen (redirect URI). Paluuosoitteen pitää olla täsmälleen sama, jonka palvelu lähettää. Se alkaa aina https://, paitsi kehityskoneella (http://localhost).
  2. Membership näyttää asiakastunnuksen (client ID) ja salaisen avaimen (client secret). Avain näytetään vain kerran.
  3. Syötä ne palvelun OpenID Connect -asetuksiin yhdessä alla olevan asetusosoitteen kanssa.

Asetukset

Asetusosoite (discovery)https://api.membership.fi/oidc/.well-known/openid-configuration
Myöntäjä (issuer)https://api.membership.fi/oidc
Kirjautuminenhttps://api.membership.fi/oidc/auth
Tokenhttps://api.membership.fi/oidc/token
Käyttäjätiedot (userinfo)https://api.membership.fi/oidc/me
Avaimet (JWKS)https://api.membership.fi/oidc/jwks
Vastaustyyppicode (authorization code flow)
Asiakkaan tunnistusclient_secret_basic tai client_secret_post
AllekirjoitusRS256
PKCES256, vapaaehtoinen mutta suositeltava

Tiedot

Pyydä scopea openid profile email membership tags. Tiedot ovat sekä ID-tokenissa että userinfo-vastauksessa.

ScopeTiedot
openidsub: pysyvä tunniste, joka ei muutu, vaikka jäsen vaihtaisi sähköpostiosoitettaan. Käytä tätä käyttäjän tunnistamiseen.
profilename, given_name, family_name, locale
emailemail, email_verified
membershiporganization_id, organization_name, membership_status (aina active), membership_role (owner, admin, viewer tai member), membership_type, member_number, member_since (YYYY-MM-DD) ja groups: ryhmien tai jaostojen nimet, joihin jäsen kuuluu.
tagstags: niiden jäsenen tunnisteiden nimet, jotka yhdistys on valinnut kerrottavaksi tälle palvelulle, esimerkiksi Verkkosivujen ylläpitäjä. Tunnisteet näkyvät muuten vain yhdistyksen ylläpitäjille, joten palvelu ei saa niistä yhtään, ennen kuin yhdistys valitsee ne palvelun asetuksista.

Puuttuvat tiedot jätetään pois, eikä niitä lähetetä arvolla null. Ryhmät ja tunnisteet tunnistetaan nimestä, joten jos yhdistys nimeää niitä uudelleen, päivitä nimet myös palvelun asetuksiin.

Jäsen hyväksyy tags-scopen erikseen. Kun yhdistys valitsee palvelulle ensimmäisen tunnisteen, jäseneltä kysytään lupaa uudelleen seuraavalla kirjautumisella, ja siihen asti tags-tietoa ei lähetetä lainkaan.

Kuka pääsee sisään

Vain yhdistyksen hyväksytyt jäsenet. Muut näkevät Membershipin sivulla, miksi kirjautuminen ei onnistu, ja palvelu saa paluuosoitteeseen virheen access_denied. Jäsenen muiden yhdistysten jäsenyydet eivät näy palvelulle koskaan.

Kun jäsenyys päättyy

Jokainen palvelu saa refresh-tokenin, joka on voimassa 30 päivää. Kun uusit sen, saat uuden ID-tokenin ajantasaisilla tiedoilla. Jos jäsenyys on päättynyt tai jäsen on perunut luvan, uusiminen epäonnistuu virheellä invalid_grant. Kirjaa käyttäjä silloin ulos palvelusta. Suosittelemme uusimaan vähintään kerran vuorokaudessa, jos palvelussa on vain jäsenille näkyvää sisältöä. Refresh-tokenin käyttö vaatii aina myös salaisen avaimen.

Istunnot

Membership tarkistaa jokaisella kirjautumisella, kuka on kirjautuneena Membershipiin juuri silloin. Jos jäsen on jo kirjautunut ja antanut luvan aiemmin, hän palaa palveluun ilman välivaihetta. Siksi pyyntö prompt=none palauttaa aina login_required. Uloskirjautuminen palvelusta ei kirjaa jäsentä ulos Membershipistä.

Palaute ja toiveet

Onko sinulla palautetta rajapinnasta tai tarvitsetko ominaisuutta, jota se ei vielä kata? Voit lähettää viestisi toivelomakkeen kautta. Lomakkeen käyttö edellyttää Membership-tiliä, ja kehittäjien toiveet huomioidaan siinä missä muidenkin käyttäjien. Yksityinen palaute näkyy vain tiimillemme, kun taas julkiset ominaisuustoiveet käsitellään ja julkaistaan toivelistalle muiden äänestettäviksi.