Portable Sessions with JSON Web Tokens
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Part Number | 66 | |
Number of Parts | 86 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/31270 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
Token ringWorkstation <Musikinstrument>Token ringRight angleWeb 2.0CodeLevel (video gaming)Video gameCASE <Informatik>DampingService (economics)Cycle (graph theory)Rule of inferenceHome pageVertex (graph theory)Cartesian coordinate systemData miningBitComputer animation
01:32
Software developerAuthenticationWeb 2.0Service (economics)Server (computing)Home pageProjective planeOpen sourceMereologyState of matterShared memoryLevel (video gaming)Moment (mathematics)Right angleCentralizer and normalizerLibrary (computing)QuicksortWordCharge carrierWeb pageXML
02:49
Web pageMobile appHTTP cookieDependent and independent variablesFlow separationGame controllerAndroid (robot)Data managementTask (computing)MathematicsCartesian coordinate systemHTTP cookieEmailWeb browserLoginMereologyAuthorizationMobile appMultiplication signNumbering schemeSpeech synthesisGateway (telecommunications)Standard deviationDecision theoryAuthenticationToken ringBitData storage deviceDiagramHome pageServer (computing)Physical systemMedical imagingDomain namePasswordWeb pageRight angleLattice (order)Resource allocationRule of inferenceForm (programming)TrailFacebookSummierbarkeitWordPoint cloudWebsiteDifferent (Kate Ryan album)DivisorCommunications protocolMessage passingSet (mathematics)Service (economics)Computer animationEngineering drawing
06:41
Message passingHTTP cookieElectronic signatureHTTP cookieCartesian coordinate systemElectronic signatureAuthenticationMessage passingXML
07:09
Dependent and independent variablesContent (media)Token ringCommunications protocolEmailDatabaseWeb browserGame controllerPoint (geometry)LoginString (computer science)HTTP cookieRandomizationMultiplication signToken ringQuery languageServer (computing)Dependent and independent variablesAuthorizationRight angleForcing (mathematics)Medical imagingComputer animation
08:31
Content (media)Information securityQuery languageEmailAuthorizationHTTP cookieToken ringMessage passingElectronic signatureComputer wormFormal verificationExecution unitAddress spacePlastikkarteSystem programmingStructured programmingStrutString (computer science)Special unitary groupWeb 2.0Message passingConnected spaceComputer wormContext awarenessMobile appInformationRight angleHome pageContent (media)AuthorizationSpacetimeIdentity managementHTTP cookieEmailWeb browserElectronic mailing listBitMultiplication signShape (magazine)Library (computing)Table (information)Data modelCryptographyShared memoryInformation securityToken ringPlastikkarteStandard deviationPhysical systemServer (computing)File formatMathematicsClient (computing)Electronic signatureString (computer science)NumberInternetworkingSystem identificationQuery languagePairwise comparisonQuicksortSign (mathematics)Different (Kate Ryan album)WordMetadataPlanningCharacteristic polynomialEndliche ModelltheorieArithmetic meanOpen setMassLogicDependent and independent variablesLoginReal numberComputer animation
14:48
AuthenticationPhysical systemHTTP cookieToken ringPasswordChi-squared distributionShared memoryFinite element methodPasswordPublic-key cryptographyPhysical systemString (computer science)RotationMessage passingNumber1 (number)Web 2.0MetadataToken ringHTTP cookieGame controllerCartesian coordinate systemMultiplication signConfiguration managementSurface3 (number)Service (economics)Response time (technology)Key (cryptography)Home pageMathematicsOcean currentRevision controlTimestampServer (computing)StatisticsCryptographyDatabaseProcess (computing)Field (computer science)EmailAuthenticationLibrary (computing)Formal languageCalculationBounded variationAsynchronous Transfer ModeDefault (computer science)Data storage deviceElectronic signatureSystem callBitQuery languageArithmetic meanMobile appDifferent (Kate Ryan album)Open setSign (mathematics)Formal verificationWeightMatching (graph theory)Computer architectureFamilyGoodness of fitImage processingDistributed computingSoftwareConfiguration spaceHypermediaArmIdentity managementAuthorizationReal numberSpiralScaling (geometry)XML
21:02
Token ringPasswordEmailLoginData conversionDedekind cutKolmogorov complexityEndliche ModelltheorieFront and back endsDependent and independent variablesWeb 2.0PasswordMultiplication signComplex (psychology)Game controllerAuthenticationNumberStandard deviationEmailPhysical systemArchaeological field surveySystem callLoginType theoryDrop (liquid)Query languageRandomizationToken ringString (computer science)ImplementationCartesian coordinate systemDatabaseSurfacePresentation of a groupField (computer science)GodSubject indexingFingerprint3 (number)Table (information)LogicData conversionGroup actionRight angleXML
23:53
AuthenticationSource codeWebsiteService (economics)Core dumpWeb 2.0Complex (psychology)AuthenticationComputer animation
24:27
Process (computing)Token ringReal numberWeb 2.0CurveConfidence intervalDisk read-and-write headService (economics)WordPresentation of a groupXMLComputer animation
25:20
Library (computing)Drop (liquid)Form (programming)Numbering schemeServer (computing)WordMultiplication signWindowToken ringError messageCategory of beingDifferent (Kate Ryan album)AuthenticationEndliche ModelltheorieMereologyLoginInformationLine (geometry)Slide rulePhysical systemKey (cryptography)Query languagePoint (geometry)Moment (mathematics)Decision theoryMobile appObservational studyGroup actionCache (computing)System administratorElectronic signatureWeb 2.0EmailInformation securityCommunications protocolHand fanHTTP cookieEquivalence relationFront and back endsGoodness of fitModal logicLecture/Conference
31:42
Coma BerenicesPower (physics)JSONXML
Transcript: English(auto-generated)
00:00
All right, good morning. Let me get started. People can come in from the hallway if they're still out. My name is Lance.
00:21
If you're here, you probably want to learn about JSON web tokens, so you're in the right place. We're gonna talk a little bit about what they are, why they exist, and maybe who cares. So they're tokens, they use JSON, and they're built for the web.
00:42
Never mind, scratch that. Now that you're all in the room, I'd like to offer you a special invite, the ground floor of mine. So I've got this idea. It's gonna be an application. You're gonna log in and you're gonna see a face. Probably your face. It's gonna fit somewhere in this like,
01:02
faces as a service vertical. I think it's gonna be pretty big. I mean, the face is gonna be pretty big, clearly. I'm calling it face page. So welcome. You're all hired. Oh, you didn't know this was an interview. I mean, you passed the code challenge
01:22
when you registered for the conference, right? So we're good? And you all have faces, so the qualifications are there. So let's go. Oh, I suppose you're wondering who you'll be working with. I'm Lance Ivy. I'm based out of Portland, Oregon. So if I seem a little out of sorts, it's because I'm trying to get used
01:41
to the bright solar radiation. I started professionally tinkering on the web as an unpaid developer in 2003. Joined some friends and colleagues from college on this startup idea in a small town of like 30,000 people. And started in front end, and the era of Netscape had just wrapped up.
02:02
So I like, opened it once, took a picture of a horribly broken rendering, and made some nice tables after that. Some things happened in 2006, 2008. I became a paid Rails developer, found my way to working on Kickstarter,
02:22
made my own share of mistakes, learned from most of them, picked up a bunch of stories. Currently, I'm working with Empotico, and also building an open source project called keratin-offn, which is an authentication server. You can imagine Devise if it were rebuilt today
02:41
as a standalone service. And this is the primary learning opportunity for the talk. So, let's get back to face page. Obviously we're gonna run face page as a standard Rails application. So, here we go. We have a few meetings, we pivot, we sprint,
03:01
we change task management systems, we iterate on faces and what they mean to our users and how they're gonna change the world, and then we deploy it. It's out in the wild, users love it. There's just one problem. People like seeing their faces on the go, and they're looking for us in the native app stores.
03:20
So, easy, right? We make an API, we build out our IOS, our Android apps, and maybe the app and the API are intertwined. JSON endpoint's the same controller. Or maybe they're name spaced, but they're still in the same app. It's a majestic monolith. Or maybe it's a standalone deployment,
03:42
but that doesn't matter. What matters is it's up in the cloud, right? It's just, it's there, it's running, it works. But something along the way has happened. We couldn't use cookies for our API. So, we implemented a quick token authentication system.
04:00
So, now we've got cookies over here, tokens over there, and this uneasy feeling that there's something similar, but we can't quit and put our finger on it, and we just keep going. But it turns out that we've actually implemented two authentication systems, and they're separate. So, this is technical debt, but we figure we can manage, it's working,
04:21
we keep moving, and just, you know, suppress those uneasy feelings into a tight little ball. Then someone on high maybe makes the decision to move to services, which, I don't know. Try it out, and we build this API gateway. But is it written in Rails? Does it speak cookies, or tokens, or both?
04:43
Do we have to retrofit our authentication schemes into it? Are we on our own? Do we have help? Do we move to something else? I mean, what happens now? Well, I wanna take a step back and consider the problem that these cookies and tokens are actually trying to solve. How did we even get here?
05:01
It's time to ask what even is logging in? What happens? What are the cookies and tokens doing? Let's dig in. We could say it starts here with a username and password. These days it could also be, you know, Facebook, or GitHub, or Google, or some other auth provider, but probably still at least passwords.
05:23
Turns out that's not really the part we care about. What we care about is how we keep track. So here's the classic way of keeping track. Browser logs in, we send back a cookie. And browsers know about cookies. They know to include them on every request back to our domain.
05:41
So every request for a face on a page is logged in. And we can show your face back. I mean, the requests that want JavaScript and CSS and images are also carrying these cookies, but that's a different talk, right? The simplest explanation for cookies is a header protocol.
06:03
When the server responds with a set cookie header, the browser knows to include it back in the cookie header. Every future request. But I think it's time to consider the elephant in the room here. What kinds of cookies are these, really?
06:22
I mean, when we diagram HTTP cookies, they usually look like this, chocolate chip or a raisin maybe. Oh, what's for lunch? But this is how we should think of them, as fortune cookies with a message inside. So Rails uses these to store bits of data in the browser, and we can crack one open and see what's inside.
06:43
Here's one that you might actually see in an actual Rails application. It's an encoded message with a signature, and you can split it apart on the double hyphens right there. Here's what's inside. There's a user ID. There's a CSRF token,
07:01
because with cookie authentication, you need that kind of thing. And there's a signature that we can use to just make sure that it's legit. So there we go. Cookies are headers on HTTP responses and requests that do things like transport a user ID back and forth.
07:21
And that's the login story we care about right now. So what's happening with the tokens on the API side of things? Well, one common convention might look like this. The server responds to a login request with some random string in the JSON body. Let's say.
07:41
And again, the device sends it back on future requests, but this time in the authorization header. Now these tokens are opaque. They're random strings. They have no meaning until we use them to find something more interesting like the user ID.
08:01
And this is good, but it's not great. On the upside, we could delete these tokens to revoke access at any point. We have some control over that. But on the downside, every API query right now involves a database query. This is, by the way, how Rails sessions used to work before switching to cookies.
08:22
And it was a performance problem. The browser submitted a session ID and used that to actually find their session from the database. All right, so let's put together what we've learned. The Rails session cookie uses a cookie header, but our API tokens use the authorization header.
08:40
The Rails session cookie is structured data, but the API is just an opaque, random string. Now the Rails session cookie can be verified with cryptography. An API token is security through queries. So can you imagine the best of both worlds?
09:00
JSON web tokens. It's signed, structured data. This is rather similar to Rails signed cookies. We've added a third segment, the header, and this just describes the format of the token. We can decode the message. What you're looking at here are called the token claims.
09:21
Now they're called claims to give you a bit of skepticism because you actually have to assert that these claims are true before you can trust it. Here's a list of common claims. You can see that they're heavily abbreviated. And the reason is because JSON web tokens are designed to fit in headers
09:41
and other character-limited small spaces. So they have to save on bytes for your more interesting content. All the claims on the left are what I consider metadata. They're claims necessary to verify that a token may be used appropriately in different situations. I'll just go through these.
10:00
The issuer describes the party that generated and signed the token. Audience describes the party that the message is intended for. These might be the same thing. It might not. Issued at is when the token was created. And expiration is when the token should be ignored. They can have a lifetime.
10:22
The claims on the right are what I consider the payload. And this is the information that you probably want to extract for your business logic. Now you can put anything you want in here as long as the issuer and the audience agree on what it means. But the common one that a lot of issuers and audiences agree on is the subject.
10:41
And this is meant to identify the party that the message is about. Or the person who owns the token, the person who has it. And this is where we put the user ID. So the JSON Web Token standard is a pretty generic thing. It's just a spec for sending secure messages.
11:01
But one of its primary uses is identity. It actually evolved in the context of OAuth and OpenID Connect. And you can see a lot of that in the claims that are built into it. So we can actually imagine it kind of like Rails cookies and API tokens. Think of it as an ID card.
11:23
Just like an ID card, it makes a number of claims. And it contains some security features. This ID card has an issuer. It's from the internet. It has a subject, the name. Has expiration and issued dates.
11:40
And it has this pretty sweet little official stamp. Security. But it's actually up to you to check the card and detect forgeries. To make sure that you can actually take this identification. So here's how you do it. One, is it from someone that we recognize as an authority?
12:02
Check the issuer. Two, was it intended for me? Check the audience. Has it expired? Check the expiration. Is it a forgery? Check the signature. Can you recreate the signature based on those values?
12:23
And last but not least, was it generated before or after that time we had to change our secret because we published it on GitHub. And you can check IssuedAt for that. If you can answer those five questions, you're in pretty good shape. And the good news is that you can get a library
12:41
to just do this for you. Okay. So we've learned that JSON Web Tokens are secure messages. Like a Rails signed session cookie. We've learned that they contain claims that we need to verify.
13:01
And we've learned about the most important claims and what they represent. So let's talk about what we can do with them. We've already mentioned identity tokens. So let's continue from there. One of the problems we had in our face page app was the duplicate authentication system.
13:23
So let's see how JSON Web Tokens can help. First let's add JSON Web Tokens to our comparison table. So while the Rails cookies are tied to the cookie header, and the API tokens use the authorization header, our JSON Web Tokens are ready for either.
13:41
They don't care. The Rails cookies were structured data signed with cryptography. And that's actually pretty good. So our JSON Web Tokens share those characteristics. So if we use an identity JSON Web Token for login, it might look like this.
14:03
Browser submits the login. Rails responds with a JSON Web Token in a cookie. The JWT contains the user ID as the subject. Now in future requests, the browser just sends it back in the cookie. And this looks pretty familiar. And that's a good thing. We actually haven't changed our headers
14:22
or the relationship between the browser and the server. We're still using cookies. We've just changed the format of the message inside the cookie. And on the API, we can drop it in here as well. There's no change to the client. They're still just sending a string back and forth. But now the string is a JSON Web Token.
14:42
It has structured data. It has meaning. It's not random. And the server can do something with it. So this is the JSON Web Token solution. One token, two headers, one authentication system. It doesn't matter whether the server finds the token inside a cookie or inside an authorization header.
15:03
It can still handle that value exactly the same and set the current user for the duration of the request. Problem number two in our face page app. Previously, the API had to execute a query on every request just to discover who was making it.
15:23
And now our API can verify the JWT with the claims and the cryptography. So this replaces a network-bound database bottleneck process with a straightforward CPU-bound calculation. This will perform faster.
15:41
This will scale better. This will introduce less variation into response times and generally just have fewer failure modes. Problem number three. Our cookies were implemented for Rails, by Rails. Now, don't get me wrong. The default Rails session store is wonderful. It works.
16:02
It's hidden. It is secure. It is very well designed. And it does the job it needs to do. But it is tightly coupled to Rails. It is tightly coupled to cookies. And it's kind of tightly coupled to Majestic monoliths. So if any of those things don't work for you, you have to ask yourself, what's next?
16:23
JSON Web Token libraries are implemented in at least 20 languages. They're decoupled from the cookies. And they contain claims that you can use to build any kind of distributed architecture. So they're more flexible. It's a more general purpose solution.
16:43
Problem number four. In a distributed architecture, you might find yourself sharing secrets so that when you sign a message with one system, you can verify it on another. And this involves trusted back channels like copy and paste. Or configuration management systems.
17:02
Now that the secret exists in more places, it's a bigger attack surface. If any one place is compromised, that secret can be used to attack all the other places as well. So what do JSON Web Tokens offer? They support asymmetric key algorithms like RSA.
17:25
Now the signature process used by Rails to sign a cookie is called HMAC. You give it a salt, it hashes the cookie. You take that salt, you rehash it later, and it verifies. Now the required setup for RSA is a little bit different.
17:40
The server signing the token needs a special RSA key, not just a random salt. It uses the private key to sign the token. But then, it can actually publish the public key on a free and open HTTP endpoint using a spec like JSON Web Keys.
18:02
When some other server receives the message, what it can do is go fetch the public key, use that to verify, and then cache that forever. So one HTTP call automatically shares the secret. But it's not a secret, it's the public key.
18:22
So this investment means that you don't need to share secrets. It's a little bit more upfront, then the operational cost is lower. This means there's no copy and paste between the systems. You just fetch the key over HTTP. There's no super coordinated lockstep deploy process when you need to change it on both places at the same time
18:42
without dropping messages in the middle. This also reduces the attack surface. A lost secret can only attack the service that leaked it. This can actually even prepare you for some really nifty, like automatic key rotation stuff. I'm not gonna get into that right now, but if you're curious how that works,
19:00
I'm happy to talk about it. Come find me around the conference. Problem number five. You thought you knew about how password resets worked. You generate and send a token. It's a nonce, it's a random string. You verify it in your controller, and then you regenerate a new token
19:20
to expire the old ones that you sent out and make sure that people can't hack the system. And when you think about it, this is actually a third authentication system. It works a lot like the opaque API tokens. And again, it's implemented as a one-off. So here's how I build a password reset JSON web token.
19:43
First, start with a standard identity token. This contains the metadata claims and the subject. Then, I add a scope claim. Now, I looked around. This one doesn't seem to be standard, and I couldn't find a better one, so I'm just calling it scope.
20:01
The idea here is that I'll configure my passwords controller to accept tokens with this scope, and I'll configure the rest of my application to reject tokens with this scope or any other scope that doesn't seem appropriate for them. Then, I add an optimistic lock.
20:21
Now, an optimistic lock is where you keep some kind of version, and every time a field updates, you increment that version. Anyone who wants to make a change has to tell you what the current version is. This way, you make sure that they don't overwrite something that changed without their knowledge. And you can achieve this with just using a timestamp.
20:40
So that's what I've done here. I'm maintaining a user's password change stat field, which is also good for other features, and then verify it against the token. If it matches, it's a go. And this effectively has the same, this effectively also expires the old reset tokens as soon as the password changes.
21:03
So here we go. Once again, we can upgrade opaque tokens into structured signed data. This is one less field in the user's table. This is one less index for your queries. But even better is that we've absorbed a third authentication system
21:20
by teaching our JSON Web Token backend about scopes, and by teaching our passwords controller about optimistic locks. Problem number six. Suppose that you're sending emails with survey links, or some other kind of strong call to action, where you need the user to click,
21:43
and you need to know who is making that click. So if you don't help them at all, they're gonna hit a login wall, and maybe they're on their phones, so they don't wanna type it in, and they just come back later, or they don't, and your conversion drops. So maybe you implement random strings,
22:00
opaque tokens, and you connect them back to the user, just like the API system. I mean, this is sounding pretty familiar, right? So we can just generalize the password reset solution. All we need is a scope claim. If it sounds like I'm suggesting that we send user sessions through email,
22:20
yeah, actually, that's exactly what I'm suggesting. I mean, that's basically what the randomly generated one-off random strings are doing. They're giving a login session by email. But this one is built into our authentication system. It's not a one-off implementation that you're gonna forget about.
22:42
All right, problem number seven. Your application is already doing lots of stuff, and you're including a lot of this common standard authentication feature stuff as if it's somehow unique. They run from the same database. They can be affected by every deploy, every upgrade,
23:00
and all this complexity is in one spot, which makes it a lot harder to audit your attack surface and understand where you need to remain secure. And let's not forget the always present user god model. And JSON web tokens can help. So they were born ready for this.
23:21
This is why the issuer and audience claims exist so they can be different things. And the issuer, let's imagine, takes responsibility for the account. And the account might be the username and the password and the last time the password was changed and how many times they've failed their login or any of that stuff.
23:41
And this leaves your application responsible for a simpler user's model. It just needs to relate the user with an account. And this is actually what I learned firsthand while working on keratin authent, which is kind of what you get if Devise was rebuilt
24:03
as a standalone authentication service. It removes the complexity from your app, relies heavily on JSON web tokens, uses every trick I've mentioned here, and then some. The core tech is pretty stable, I think, and I've got some ideas for some advanced features.
24:22
So if this is interesting to anybody, I'd love to chat about it. Alright, in conclusion, these are the things I hope you take away from the presentation. One, you can use JSON web tokens right now. It doesn't matter if you have a monolith or services,
24:42
you probably recognized one or more of these problems. Two, JSON web tokens have a low learning curve and a high skill ceiling. There's a lot more that you can do with them as you gain confidence. But all you need to do is start somewhere. So you're probably gonna go home from this conference
25:02
with a head full of ideas for things that you wish you could use at your day job and all this cool stuff that you wanna try. And maybe JSON web tokens is one of those. Pick something. Learn it by doing it. Try it out. And make your knowledge real.
25:32
And we do have time for questions. So the question is, if the user has been disabled by an admin since they logged in,
25:42
how can you immediately log them out and make sure that they don't come back? You can create, for example, a blacklist and keep this temporary cache of invalidated tokens. You can, if you choose to for critical actions,
26:00
implement a revalidation. But yeah, the trade-off is real. The trade-off is real. If you keep authentication in a token that lives for 30 minutes or something, that's the other thing. I do recommend that these tokens have a short life and that you regenerate them frequently. So the time window for that kind of problem is small.
26:23
Yeah, so again, the comment is that checking this blacklist takes time. So I recommend deciding which endpoints are critical and revalidating for just those endpoints. There are probably a lot of things where it's okay if they can continue to read data for a few more minutes
26:42
or maybe what you wanna do is protect that data and you can choose to revalidate where necessary. Great. Well, you can try JSON Web Tokens in an existing app by finding any kind of opaque token and seeing how you can replace it. So that's one way to try it out. If you wanna try an authentication server, then it helps to have an app
27:01
with some kind of login scheme where you just swap out where the form submits. So the form might submit to your back end and now the form submits to a different back end. Those are two ideas. Is there a drop-in replacement?
27:21
There's a library called Knock and Knock is devised with JWT but it's built into the monolith. So an authentication server's gonna run as a separate deployment but Knock will use JWT
27:41
as part of the same monolith. Refreshing the tokens with more tokens. So the way that I've seen is where you maintain what's called an access token and a refresh token. And the access token is what you're sending to the API. The refresh token is more secure
28:03
because it's not used for very much. The one thing it's used for is getting new access tokens. So let's say that your access token is good for an hour and let's say that you decide every 30 minutes way before that's gonna expire, you use the refresh token to get a new one.
28:23
What you can do is build revocation into that refresh system. So the refresh maybe actually does a Redis query or a MySQL query or something to make sure that it's still okay to generate new access tokens. The dual token system means that one
28:41
can have different security properties and the other is used for your really chatty protocols because it's lightweight and doesn't require queries. And they're kept in different places with different security properties. Yeah, so the comment or the idea was that
29:01
if you attempt to use a token and the error is that it's expired, you might decide it's time to get a new one. And that's definitely like the fail safe. I think that aggressively refreshing them before that happens is a cleaner experience. And if you refresh well enough, you may or may not need that kind of last moment,
29:24
it's expired, let's get a new one thing. Yeah, that's the IssuedAt check. So in that kind of dire situation, which we all hope isn't happening,
29:40
there's really no going back. You generate a new key and start using it. And then what you do is you roll out this idea of an epoch and you say any token generated before this point in time was using an old key that we don't trust anymore. So if the IssuedAt is before last Friday
30:03
when this happened, then just throw it away and that means people are logged out. Oh, so the comment was that you might have multiple keys and so you need an epoch per key. JSON Web Tokens has a claim called key ID. So you can embed within each JWT
30:23
a signature of the key that was being used and that will let you, if you have per key revocation, tell exactly which one was being used and whether it's still trustworthy. For a simple login for sessions, it's just what you saw.
30:43
It's the user ID. If you choose to put them in a cookie, then you need to also figure out CSRF. And you can put that CSRF token in the JWT because it's open, like you can add more stuff into it and solve those same problems. I'm actually not a big fan of keeping
31:02
a lot of data in sessions anyway. So I want to say on the slide, it was like two or three lines. It was maybe 50% longer than a Rails equivalent cookie. Some people advocate for keeping more user information in there, like are they an admin? What permissions do they have?
31:23
What's their name and email so you can save more queries that way? The downside is, as mentioned earlier, you have to decide how much you care about that information getting stale. All right, I think we're good.