In navolging van mijn vorige topic (Moet altijd alles een moderne SPA zijn?) - waardoor ik tot de conclusie gekomen ben dat ik voor de meeste projecten die ik doe, wel degelijk beter Single Page Applications kan bouwen - hou ik mij nu bezig met het sessie management in combinatie met SPA's.
Omdat ik zelf met Angular, .NET Core en SQL Server werk, zal ik dit vaak als voorbeeld aanhalen. Maar ik ben ook benieuwd hoe mensen met andere stacks het doen.
Van wat ik tot nu toe heb begrepen, zijn er grofweg 2 manieren om sessie management te doen.
1. JSON Web Tokens (JWT)
Zo ongeveer elk voorbeeld dat je op internet kunt vinden, gebruikt JWT om in een Angular applicatie iets van authorisatie in te bouwen. Het idee is dat je bij de server een token opvraagt op basis van bijvoorbeeld credentials en dat de server dan jou voorziet van een token met een beperkte geldigheid waarin bepaalde claims staan.
Om zeker te zijn dat deze claims waar zijn, is het token voorzien van een signature. Wanneer je vervolgens requests doet naar de server met dit token, dan kan het token gevalideerd worden om te controleren of de claims waar zijn.
Een voordeel van JWT is vooral de schaalbaarheid. Omdat niet voor elke request een login server / database geraadpleegd hoeft te worden - kun je in potentie veel meer requests aan.
Er kleven echter ook nadelen aan het gebruik van JSON Web Tokens. Als je namelijk iets van een sessie wil nabootsen, dan zul je tokens moeten kunnen refreshen. Wanneer dit niet goed geïmplementeerd wordt, kan hier van alles bij misgaan (refresh tokens mogen maar 1 keer gebruikt worden etc).
Daarnaast kun je een sessie niet actief beëindigen. Als iemand een geldig token heeft, dan blijft dat geldig totdat het verlopen is en kun je daar weinig aan doen.
In de praktijk zie ik dat mensen hier vaak wat mee aanrommelen. Ze gebruiken tokens die te lang geldig blijven, verzinnen gekke systemen om ze te refreshen, slaan tokens op in local storage enzovoorts.
2. Framework session management
Hierbij laat je het server side framework (in mijn geval .NET Core) de sessies managen. Om dit goed te laten samenwerken met Angular, dwing je af dat het gebruik van cookies essentieel is. Daarnaast vertel je Angular dat alle requests de optie "withCredentials" moeten gebruiken.
Het grote voordeel hiervan is dat server side frameworks vaak battle tested session management aan boord hebben, dat vaak makkelijk te configureren is en eenvoudiger te gebruiken is dan met JWT aan de slag te gaan.
Ook is deze oplossing heel veilig te maken, door cookies te gebruiken die een stricte SameSite policy hebben, HttpOnly en Secure zijn. Bovendien wordt de inhoud van het cookie door .NET Core versleuteld en kan automatisch de sessie ververst worden.
Potentiële nadelen zitten vooral op het front van schaalbaarheid, maar zijn oplosbaar:
Als je horizontaal moet schalen / load balancen dan kun je een in memory store (REDIS) of een persistente store (SQL Server / andere database) gebruiken voor de sessies.
De SPA en de API moeten - wat de browser betreft - op hetzelfde domein gehost worden. Anders wordt de cookie gezien als een third party cookie en wordt hij niet opgeslagen. Dit doen browsers om de privacy van de gebruiker te beschermen, omdat veel advertentieplatforms tracking cookies plaatsen.
Meestal is dit op te lossen door een reverse proxy te gebruiken, of door de SPA samen met de server applicatie te deployen.
Mijn vraag
Wat is nou best practice?
Het lijkt tegenwoordig alsof iedereen overal JWT of een andere vorm van token authenticatie gebruikt als je gaat zoeken op internet, maar is dat wel zo?
Hoeveel mensen hier gebruiken bijvoorbeeld de sessies van het server side framework in combinatie met een SPA?
Ik ben benieuwd
Omdat ik zelf met Angular, .NET Core en SQL Server werk, zal ik dit vaak als voorbeeld aanhalen. Maar ik ben ook benieuwd hoe mensen met andere stacks het doen.
Van wat ik tot nu toe heb begrepen, zijn er grofweg 2 manieren om sessie management te doen.
1. JSON Web Tokens (JWT)
Zo ongeveer elk voorbeeld dat je op internet kunt vinden, gebruikt JWT om in een Angular applicatie iets van authorisatie in te bouwen. Het idee is dat je bij de server een token opvraagt op basis van bijvoorbeeld credentials en dat de server dan jou voorziet van een token met een beperkte geldigheid waarin bepaalde claims staan.
Om zeker te zijn dat deze claims waar zijn, is het token voorzien van een signature. Wanneer je vervolgens requests doet naar de server met dit token, dan kan het token gevalideerd worden om te controleren of de claims waar zijn.
Een voordeel van JWT is vooral de schaalbaarheid. Omdat niet voor elke request een login server / database geraadpleegd hoeft te worden - kun je in potentie veel meer requests aan.
Er kleven echter ook nadelen aan het gebruik van JSON Web Tokens. Als je namelijk iets van een sessie wil nabootsen, dan zul je tokens moeten kunnen refreshen. Wanneer dit niet goed geïmplementeerd wordt, kan hier van alles bij misgaan (refresh tokens mogen maar 1 keer gebruikt worden etc).
Daarnaast kun je een sessie niet actief beëindigen. Als iemand een geldig token heeft, dan blijft dat geldig totdat het verlopen is en kun je daar weinig aan doen.
In de praktijk zie ik dat mensen hier vaak wat mee aanrommelen. Ze gebruiken tokens die te lang geldig blijven, verzinnen gekke systemen om ze te refreshen, slaan tokens op in local storage enzovoorts.
2. Framework session management
Hierbij laat je het server side framework (in mijn geval .NET Core) de sessies managen. Om dit goed te laten samenwerken met Angular, dwing je af dat het gebruik van cookies essentieel is. Daarnaast vertel je Angular dat alle requests de optie "withCredentials" moeten gebruiken.
Het grote voordeel hiervan is dat server side frameworks vaak battle tested session management aan boord hebben, dat vaak makkelijk te configureren is en eenvoudiger te gebruiken is dan met JWT aan de slag te gaan.
Ook is deze oplossing heel veilig te maken, door cookies te gebruiken die een stricte SameSite policy hebben, HttpOnly en Secure zijn. Bovendien wordt de inhoud van het cookie door .NET Core versleuteld en kan automatisch de sessie ververst worden.
Potentiële nadelen zitten vooral op het front van schaalbaarheid, maar zijn oplosbaar:
Als je horizontaal moet schalen / load balancen dan kun je een in memory store (REDIS) of een persistente store (SQL Server / andere database) gebruiken voor de sessies.
De SPA en de API moeten - wat de browser betreft - op hetzelfde domein gehost worden. Anders wordt de cookie gezien als een third party cookie en wordt hij niet opgeslagen. Dit doen browsers om de privacy van de gebruiker te beschermen, omdat veel advertentieplatforms tracking cookies plaatsen.
Meestal is dit op te lossen door een reverse proxy te gebruiken, of door de SPA samen met de server applicatie te deployen.
Mijn vraag
Wat is nou best practice?
Het lijkt tegenwoordig alsof iedereen overal JWT of een andere vorm van token authenticatie gebruikt als je gaat zoeken op internet, maar is dat wel zo?
Hoeveel mensen hier gebruiken bijvoorbeeld de sessies van het server side framework in combinatie met een SPA?
Ik ben benieuwd
Ask yourself if you are happy and then you cease to be.