Gedeelde oauth token over meerdere users (Exact Online)

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • cooper87
  • Registratie: December 2012
  • Laatst online: 22:50
Weet even geen betere topic titel, maar hopelijk kan ik het probleem duidelijk uitleggen.

Ik heb een nodejs REST api als backend en een php applicatie als frontend. De api gebruikt oauth als authenticatie en alle api calls returnen dus gepersonaliseerde results op basis van de bearer token.

De nodejs api leest (o.a.) data uit Exact Online. Bijvoorbeeld de url: https://mijn.api/1.0/invoices leest alle facturen uit van de klant die aan de bearer token gekoppeld staat.

De Exact Online REST api gebruikt ook oauth authenticatie. De access tokens zijn 10 minuten geldig en kunnen daarna weer gerefreshed worden.

Het probleem is nu als volgt. Ik sla 1 access/refresh token op in de api (mongodb) en alle calls uit mijn node api die iets met Exact doen gebruiken deze tokens (elke user binnen mijn api gebruikt dus dezelfde access tokens richting Exact). Dit is niet wenselijk wanneer meerdere users tegelijkertijd van de api gebruik maken (wat zeker weten gaat gebeuren) en de access token gaat verlopen. Hierbij heb je potentieel een probleem wanneer een refresh token voor gebruiker A ingewisseld wordt terwijl gebruiker B nog middenin een chain van API calls zit (tenzij je voor élke API call de access/refresh token weer uit mongo ophaalt, maar dat is ook geen schaalbare oplossing, voor sommige functionaliteiten moet ik 4 calls achter elkaar naar Exact uitvoeren).

Het is echter niet mogelijk (zover ik weet) om meerdere access tokens tegelijkertijd actief te hebben binnen Exact Online: wanneer ik een nieuwe access token aanvraag, is de oude niet meer geldig. Ik kan er dus maximaal 1 gebruiken/opslaan.

De enige oplossing die ik kan bedenken is om de facturen/PDF's met een cronjob uit Exact op te halen en op te slaan op een tussen locatie, gekoppeld aan de juiste gebruikers. De api calls zelf hoeven dan niet meer uit Exact data op te halen. Ik wil echter liever niet dezelfde data 2x opslaan (zeker omdat het aantal facturen hopelijk hoog op kan lopen) omdat je dan weer een extra laag met foutgevoeligheid introduceert.

Ik hoop dat het probleem helder is en ben benieuwd of iemand een briljante ingeving heeft.

[ Voor 5% gewijzigd door cooper87 op 12-04-2015 21:16 ]


Acties:
  • 0 Henk 'm!

  • Pizzalucht
  • Registratie: Januari 2011
  • Laatst online: 21:27

Pizzalucht

Snotneus.

Als ik je verhaal goed begrijp gebruiken alle gebruikers in jouw applicatie dezelfde gebruiker in Exact Online?
Dan is het inderdaad niet mogelijk om meerdere tokens per applicatie te hebben. Bij het refreshen van de token verloopt de vorige.

Misschien kun je iets proberen met locking?
Ik zou denk ik werken met 2 locks:
- In use lock
- Being refreshed lock

Op het moment dat de 1e lock erop zit wacht de refresh functionaliteit tot de lock eraf is.
Op het moment dat de 2e lock erop zit wachten alle API calls met data ophalen tot de lock eraf is.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ik snap niet waarom je mongo zou gebruiken. Ik zou het geheugen van node zelf gebruiken, of heb je meer dan 1 node event loop? Ik zou dus gewoon een aantal dingen bijhouden in het geheugen van node:

-de token (of null bij nog niet verkregen/refresh actief)
-tot wanneer token geldig
-aantal actieve requests (we doen alleen refresh bij 0; "in use lock" van post hierboven)
-queue met functies/requests die je wil gaan doen als je een nieuwe token hebt verkregen.
-of een refresh call aan de gang is (indien ja, voeg dingen toe aan queue, "being refreshed lock" van post hierboven)
-of je een refresh wil doen als actieve request leeg is (indien ja, voeg dingen toe aan queue ipv nieuwe aanroep)

Als je requests dan allemaal via dezelfde centrale functies/callbacks gaan dan lijkt het mij relatief eenvoudig om uit te programmeren.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • cooper87
  • Registratie: December 2012
  • Laatst online: 22:50
Ik gebruik mongo om de allereerste access/refresh token mee op te slaan. Via Exact moet dit via de browser, waar je ook echt moet inloggen met je Exact account. Daarna komt er een callback naar een url met access token. Zie ook hier, het stukje over authorization code.

Dit voer ik uit via een php frontend die vervolgens een api call maakt naar node om de tokens op te slaan in mongo. Als ik de tokens in het geheugen op wil slaan, dan betekent dit dat ik elke keer die handmatige stap moet uitvoeren bij een restart/crash/etc, dat is niet wenselijk. Nu voer ik het 1x uit per omgeving (productie administratie en test administratie) en kan ik vanaf dan uit de voeten (refresh tokens zijn een jaar geldig).

[ Voor 13% gewijzigd door cooper87 op 12-04-2015 22:05 ]


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Dan zou ik de token alleen bij de start van de app uit mongo lezen, en bij iedere wijziging opslaan als de oude ongeldig wordt.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Pizzalucht
  • Registratie: Januari 2011
  • Laatst online: 21:27

Pizzalucht

Snotneus.

Het opslaan van de token heeft best wel wat voordelen op het moment dat je wilt gaan schalen naar meerdere "webworkers". Locken kan je dan bijvoorbeeld met https://github.com/errorception/redis-lock doen.

Ga je daar nooit behoefte aan hebben dan kan je denk ik wel wat met de tips uit de post van pedorus.

Ik heb trouwens ook zo'n systeem gemaakt in NodeJS om data van Exact Online te halen (en andere boekhoudsystemen), maar die is volledig gebaseerd op tasks in een queue en ik heb zo'n gevoel dat je applicatie al te ver is om zoiets nog in te bouwen.

[ Voor 29% gewijzigd door Pizzalucht op 13-04-2015 08:18 ]


Acties:
  • 0 Henk 'm!

  • cooper87
  • Registratie: December 2012
  • Laatst online: 22:50
Edit: ik heb nu dit bedacht (adv jullie feedback):
  • Applicatie start => haal laatst bekende access token/refresh token/expiration date uit mongodb
  • Stop deze data in lokale cache (zoiets: https://github.com/tcs-de/nodecache)
  • Stop alle api calls in een queue
  • Queue controleert of token gerefreshed moet worden
  • Zo nee, prima, call uitvoeren en result returnen
  • Zo ja, token refreshen en mongodb/cache updaten, daarna pas de call uitvoeren
Het nadeel hiervan is natuurlijk dat je niet kan opschalen met meerdere nodes, dan zal de cache naar een shared iets als redis moeten, maar dat kan tzt. In elk geval lijkt het me qua performance beter om uit cache te lezen dan voor elke api call mongodb te moeten queryen.

[ Voor 124% gewijzigd door cooper87 op 13-04-2015 10:42 ]

Pagina: 1