Tijdens één handtekening wisselen drie oppervlakken elkaar af: jouw pagina's, Cleverbase's pagina's in dezelfde browser, en de Cleverbase-app op de telefoon van de ondertekenaar. Alleen het eerste is van jou. De Cleverbase-pagina's en de app-schermen horen bij de gekwalificeerde dienst en kunnen niet worden gestyled, geframed, ingebed of vervangen: daar wordt de ondertekenaar verteld wat hij gaat ondertekenen, en daar wordt de uitsluitende controle over de sleutel uitgeoefend. Ontwerp je flow eromheen, niet eroverheen.
Loop het hieronder door; de browserkolom en de telefoonkolom laten per moment zien van wie het scherm is, en wat je backend ondertussen doet.
Van wie is welk scherm
| Oppervlak | Eigenaar | Wat jij bepaalt |
|---|---|---|
| De pagina met het document en de knop "Ondertekenen" | Jij | Alles |
| De autorisatiepagina's (inloggen, QR, toestemming, wachten, resultaat) | Cleverbase | Niets, behalve de redirect_uri waar je de ondertekenaar naar terugstuurt en het moment waarop je begint |
| De app-schermen (verzoek, pincode, resultaat) | Cleverbase | Niets |
| De pagina waar de ondertekenaar daarna landt | Jij | Alles |
De Cleverbase-pagina's komen van de host in je autorisatie-URL: connect.cleverbase.com, of connect.acc.cleverbase.com op acceptatie. Open ze niet in een iframe of een webview die je zelf beheert; behandel ze als een redirect over de hele pagina, zoals je bij een betaaldienst zou doen.
Desktop en mobiel zijn niet dezelfde flow
- Desktop. De eerste Cleverbase-pagina toont een QR-code. De ondertekenaar scant die met de Cleverbase-app, en de browserpagina loopt zelf door zodra de app heeft bevestigd. Twee apparaten, één sessie, aan elkaar gebonden door die scan. De tweede autorisatie vraagt niet om opnieuw scannen: die hergebruikt die binding, dus de browser toont dan een wachtscherm met de voortgang van de ondertekenaar terwijl de app om de bevestiging en de pincode vraagt.
- Mobiel. Dezelfde URL opent de app direct via een app-link, dus de QR-stap verschijnt niet. De ondertekenaar komt via de redirect terug in de browser.
Dat verschil is onzichtbaar in je code, want het is dezelfde /oauth2/authorize-aanroep, maar heel zichtbaar bij het testen: op een telefoon zie je nooit een QR-code, en op een desktop heb je altijd een tweede apparaat nodig.
Twee redirects, en wat er terugkomt
Beide autorisaties eindigen in een redirect naar je redirect_uri. Dat is je callback, en er is geen andere: Cleverbase roept je backend niet aan, er is geen webhook en geen server-naar-server-melding. Als de ondertekenaar nooit terugkomt, vertelt niets je dat.
| Gelukt | Weigeren, verlopen of weglopen | |
|---|---|---|
Eerste rondgang (scope=service) | ?code=...&state=... | ?error=...&state=... |
Tweede rondgang (scope=credential) | ?code=...&state=..., in te wisselen voor de SAD | ?error=...&state=..., er is niets ondertekend |
Bouw dus per rondgang voor drie uitkomsten, niet twee: gelukt, een error-redirect, en stilte. Stilte is in de praktijk de gewone: de ondertekenaar sluit de tab, verliest zijn app-sessie of loopt weg. Bewaar de tussenstand onder je eigen state-waarde met een eigen time-out en ruim hem op; onze eigen implementatie laat hem na tien minuten verlopen.
Nog twee dingen over de redirect:
stateis van jou en eenmalig. Zo vind je het voorbereide document, de digest en het ondertekentijdstip terug als de browser terugkomt. Haal hem weg zodra je hem gebruikt, zodat een herhaalde redirect geen tweede handtekening kan starten.- De ondertekenaar kan op een ander apparaat of in een andere tab terugkomen dan waar hij vertrok, vooral op mobiel. Als je sessiecookie het enige is dat de redirect aan de flow bindt, breekt dat; de
state-parameter is de betrouwbare schakel.
Wat de ondertekenaar over het document te zien krijgt
De app laat zien wie om een handtekening vraagt, niet wat er in het document staat. Cleverbase krijgt het document nooit, dus kan het ook niet tonen. De ondertekenaar leest het document op jouw pagina, voordat de flow begint, en bevestigt daarna in de app.
Dat heeft een gevolg voor je interface: het document dat de ondertekenaar las en de hash die je autoriseert moeten hetzelfde zijn. Toon het document, start dan de flow, en laat er niets tussendoor de PDF opnieuw genereren.
Timing waar je op moet ontwerpen
- De SAD uit de tweede rondgang is 300 seconden geldig en alleen voor de hash of hashes die je autoriseerde. Roep
signHashdirect aan, in de redirect-handler, niet vanuit een wachtrij die later kan lopen. - Het access token uit de eerste rondgang leeft lang genoeg voor
credentials/list,credentials/infoen, later,signHash. Houd het de hele flow vast. - Tussen de twee rondgangen zit jouw eigen werk (voorbereiden en digesten). Doe dat in de eerste redirect-handler en heb de tweede autorisatie-URL klaar voordat je de ondertekenaar doorstuurt, zodat hij niet naar een spinner kijkt.
Dit testen
- Je hebt een echte telefoon met de Cleverbase-app nodig, geregistreerd op dezelfde omgeving (de acceptatie-app voor
connect.acc). Er is geen emulator en geen testmodus die de app overslaat. - Test het weigerpad. Tik "Weigeren" in de app en controleer dat je code de
error-redirect verwerkt en de voorbereide stand opruimt. - Test het stiltepad. Sluit de tab op de Cleverbase-pagina en controleer dat er niets blijft hangen en er geen half voorbereid document achterblijft.
- Test het verlooppad. Autoriseer en wacht dan meer dan vijf minuten voordat je
signHashaanroept; dat moet mislukken en een nieuwe autorisatie vragen. Beter dat je dat één keer in een test ziet dan bij een klant. - Test op een telefoon en op een desktop. Het zijn verschillende reizen voor de ondertekenaar, en de mobiele slaat een scherm over waar je misschien tekst omheen hebt gebouwd.
- Handtekeningen op acceptatie gebruiken testcertificaten en zijn niet gekwalificeerd, maar de schermen en de tijden zijn de echte.
Wat Cleverbase niet doet
- Geen opslag van documenten. De PDF blijft bij jou, de hele flow en daarna. Er valt later niets op te halen.
- Geen tijdstempel in de handtekening. Een gekwalificeerde tijdstempel is een aparte aanroep naar een TSA, door jou. Zie het hoofdstuk over de niveaus.
- Geen webhook. Alleen de redirects hierboven.
- Geen maatwerk in de pagina's of de app. Niet het logo, niet de teksten, niet de volgorde van de schermen.