 Good morning everyone. How are you doing? Great. Alright, so a couple of years ago I had a mission. My mission was to create an API. Not a very fancy API though, but a RESTful API with the hypermedia stuff and a simple authentication method. Then I said, yeah, alright, I am ready. But there was some weird stuff happening because I had to create some tokens in order to say basically exchange your credentials for a token so you can use the API back and forth, but that token should expire. Okay, I will just store that information in the database. It's the most natural way to do that. Some months later I was asked to do like, now we have two clients. Some tokens can only be used by one of these clients. Okay, let's stuck that into the database again. More of these things kept coming and you can see that it was wonderful. Everything was perfect, but no. The database was a mess. We had expired tokens in the database. We had a lot of issues there. And when I looked at that mess, I said, okay, I'm done. We need something simple in order to work. Yeah, my clicker is not good. We needed simple. And my name is Luis Kobuchi. I'm a Brazilian developer living in Amsterdam. I help Okramius to break doctrine. I also help Raphael to ruin everything on Amsterdam PHP. I work at Verksport, a Dutch company that also has some business in Italy as Instapro. And after I went through all these database troubles, I found something very interesting. It was a work that started in 2012. It was basically to have smart tokens. Self, everything was in the token and it was very easy to understand and how to use it. The name of it was G-Zone Web Tokens. In order to start this, the best thing I can do is to show a token for you. This is a token. It looks familiar, right? Oh, come on. This looks like base64 encoding strings, right? A bit, because it is kind of a base64 encoding. For those that doesn't know about base64, just keep one thing in mind. It's not encryption. That's enough. Basically, it's a way to have binary-safe strings. If you have a string that contains binary data, you can just encode it with that algorithm and you can just pass it around and it will be safe. The problem is, we have some dots here. Base64 encoding doesn't have dots. The idea of the dots is to serve as separators. There's another difference here in this encoded string because it's a variation of a base64 encoding. It's what we call base64 URL. Basically, it converts some characters in order to make it safe to be passed in a query string or basically on a URL, any part of it. Okay. Now that we know how to decode this token, let's apply that algorithm. The result will be this. Yeah, we have a JSON. Perfect. We can do all sorts of things. We can store anything in the JSON and pass it around. The first use case or the most common use case is about authorization and authentication where you have two sides of it, the client and an API. The client basically presents the credentials. The API validates the credentials. This is basically an example of the object that you can use as JSON content. We're going to talk about what does it mean. And the API sends the token back. And for next request, the token will be passed as authorization header. And the API will be able to say, okay, is the signature valid? Is this client allowed to use this token? The issuer was me or somebody else issued this token. And can this token be used at this moment? Another common use case, and that helps a lot, is links. Have you ever needed to create a reset password token or email? And you needed to store things in the database or find a way to be able to expire this token. With JSON WebToken, it makes very simple because you can set, okay, the expiration of this token is in two days. So the user is the user 1, 2, or 3. You will have a string, and you can just pass it on the URL. The same thing happens with the pages that you need. The user must be logged to use the content. And you want to, from an email, you want to log in the user. You can also use the JSON WebToken to do that. CSRF validation. Okramius created this library that basically puts the ID. So let's go back a bit. CSRF is basically a security measure to make sure that nobody is... The user sending the form is the right user, and you certify that. So usually you put a token in your session, and this goes also in the form. When you have the request, you receive the token on the form and validates, okay, is this the same token or not. So you can also use JSON WebToken to implement that. So the token that goes in the form is a smart token. It's the one that knows about expiration and all sorts of things. So this library is pretty nice and helps you to manipulate this inside forms. And a different use case is regarding sessions. The standard PHP session basically works with cookies, right? So you have something, some data that the web server stores into a file, gets another identifier, and sends it back to the client, right? That happens when you do a session start, view everything on the session Superglobal, and ends the request, and you have the session there. On the next request, the client will send the same identifier, and the server will know, okay, I will fetch the file with that name, and I will know all the data that is stored there. This involves storing, so IO, also serializing, because session data is serialized in order to be stored into a file. And there's an issue that if you have this kind of setup, you just have basically two choices. Either you remove the storage from the web server, or you just say, okay, the load balancer will do a sticky session, so if the client was processed on the server one, it will always go to the server one. This involves a lot of things, and also relying on Superglobal is not really cool, right? So if you want, you can use a JSON web token that basically contains the session data, and it's passed to any web server, and anyone can process that request. Of course, it has some limitations, it has some issues that you need to understand, because, well, Base64 is not encryption, do you remember? So you need to ensure that you're not saving sensitive data inside of the token. Another library that you can use is this one that we created together, Kramius, me, and Malukinyu. And it's basically a meteor that you can use to create and manipulate sessions using JSON web tokens. Now that you have some ideas on how a token can be used, let's see and understand it better on how things work there. As you saw, we had these two JSON objects there. The first one represents the headers. The headers basically have the information that you need to know in order to decode that token. So you will have a type, you will have an algorithm. You can have a key ID as Adam shown on his talk yesterday. And you also have a list of claims. Basically, we have three kinds of claims in the JSON token, a web token specification. The public claims, the registered claims, and the private claims. The list of registered claims is this one. So the idea of a JSON web token is to be compact. So the registered claims in the standard claims where you can use and nobody can collide with them, it's basically this one. We have on the top the token ID, which is the identifier for the token. The issuer, so what was the server or the host name that issued the token, basically an identification for that. The audience of the token, so what are the clients that are permitted to consume this token or to use that token? So it can be just a single string or URI or an array of strings. The subjects of the token, what the token relates to, and finally the three informations about dates. Issue that when a token was created, expiration and not before, which is basically the minimum time where the token can be used. So these three are very powerful because you can say, I'm creating the token now. It can only be used till tomorrow, but it cannot be used before or five minutes from now. So you can specify a very good range. And this numeric date usually is represented using UNIX timestamp as an integer, but it can also be a string so it will be a timestamp with microseconds. So it's very powerful. So how to manage that is really nice. The first register claims are case sensitive. So when you're validating them, you must be sure that you're doing in a right way. Apart from the register claims, we have the idea of public claims. Public claims are basically claims that people from all around the world are using all the time the same claims. So it can be standardized sometime. So we reserve them as public for some time and then we register them. The private claims, the claims that you want to use can be anything. It would be nice to keep the idea of short identifiers. So you don't use a lot of space. Because, again, it's a base 64 URL encryption encoding. So just to see if you're awake or not. So this encoded string will increase in size according to the data that is stored there. And it can get very big. So looking at it, this is the token. This is the content of the token. And if we apply the encoding, we have the encoded result. But I want to point you that there's an ID there. So if I just encode it, it will be this, but it cannot be trusted. Because it's not encryption. Anyone can just decode a token, change the data, and pass it back to you. So how do you ensure the integrity of a token? We use signatures for that. Basically, you get the headers and the claims in code. Use the dot as a separator. And this string will be a payload for a signature algorithm that you now basically say, okay, this is my key, this is my payload, create a hash for me, and I will use this hash as signature. Again, this signature is encoded with the same algorithm. So the same example using this key will create this token. Now, this is trustable because if somebody changes the content, the signature will not match. So unless they have your signing key, which is not recommended, right? Enough of this. Let's see some PHP because after all, we are in a PHP conference, right? So as I said, the whole thing was created and this movement of JSON web tokens started in 2012. In 2014, I've created this library, or I started this library. It's being used pretty well, and we're very close to releasing a new major version because nobody uses PHP 5 anymore, so... Oh, come on! Yeah, so I'm dropping PHP 5 and I'm dropping support of PHP 7 as well. We'll support 7.1. Yeah, because nullable types and void are awesome. So what I'm going to show here is basically the usage of this new API. Everything starts with a configuration that basically is used as a small dependence injection container because all the objects, some objects like the buter or the parser, they have some dependencies and if you are to pass these dependencies, you can get very complicated. So, yeah, let's put it in an easy way. This configuration was basically... We'll hold the validator, the buter, and the parser. So here we're building a configuration for an asymmetric signer that's using RSA and you just pass two keys because it's asymmetric. We're going to talk about this in a few moments. And so you have to specify the private key and the public key. Then you start building your token. You get a configuration object and you're saying, okay, this token is identified by this ID, was issued by this host. This is the list of permitted clients, was issued at now. It's valid for one hour and can only be used after 30 seconds from now. And I have a private claim here. It's not that short. It says user ID is one. And I just get a token passing the signer and the signing key. And if I do a two string or I do a typecast for a string, I will have my token as string. This token is an object that is immutable. So once it's created, you cannot modify anything. The result of this typecast will be this string, which is very long, but you can see, we cannot find easily the dots there, but most of it is basically the signature. It's using RSA. And if I want to parse the token, I just get it, the JSON string, the JSON web token, go to the parser, and I have my object back. Okay, so I know how to create a token using PHP. I know how to parse a token using PHP. But I need to validate it. Because, yeah, what I'm doing with a string and with a data, I was not the one that created the token and this is not my signature. I need to validate it. Using the library, there are two methods that you can call to validate the token. One is basically, you get the validator and you call validate that will return true or false if the token is valid or not. Or you can use assert and it will raise an exception if the token is invalid based on the constraint list that you're passing. You can create customized validators or constraints if you want to check like, okay, the user ID must be an integer and must exist in my database. So you can create a validation for that if you want. Here I'm basically checking if the token was issued by me. It's permitted for this client and it's valid at now and it was signed with my signer and verification key which is my public key. If you want more libraries, we have this page which is very, very nice because you can read there on top. There's a debugger where you can just put a token there and say, okay, is this token valid what it contains? What is its body and its headers? You can easily see. And also for RSA and HMAC you can validate the signature. You can have a filter there that says, okay, I want to see all the PHP implementations or the Java implementations, JavaScript, Go, whatever. You can just go there and see. Okay guys, so we saw what is a JSON web token. We saw how to use it, some ideas. It's important to say that your imagination is the limit. You can use in all sorts of ways. I was talking with Kramius some days ago and he had an idea to use it with captures so you can validate that and pass the token instead of putting things into the session. Yeah, you can do that. On these years that I maintained this library I got, I had some questions about the JSON web token usage and so I'm basically bringing them. First question is is it a replacement for OAuth? Short answer, no. The idea of a JSON web token is basically to be a token. It doesn't say that you need to use to create these authorization and authentication flow. That's up to you. In fact, you can also combine the JSON web token with the OAuth. If you see the OAuth server of the PHP League you will see that we have JSON web token support there. And it works fine. The access key and also the refresh key you can use JSON web tokens there. What is the best algorithm to create your signatures? Yeah, that's a question that you will hear a lot. Again, the short answer is just go for asymmetric algorithms like RSA or ECDSA. We have untrusted tokens, like the ones that doesn't have a signature. And we have HMAC. The problem with HMAC is that it is a symmetric algorithm. It has only one key. That means that if you need to verify your signature in a different place you need to share that key. That's why I recommend to use either RSA or ECDSA. The difference between them I must be honest, I don't know for sure. I know that one use elliptic curves sorry for the bad English but the idea is that you have some mathematical curves and you just use there. And the other is RSA, I think you probably know a bit. So the idea of them are like when to use one or the other. ECDSA I know that it creates a shorter signature. So if you really need that and that's your only concern, go for that. If you need more information about cryptography please, you have Scott and Chris that are very good on that. How to block tokens? Yeah, that's a very good question because once a token was created it's there because there's no way to know if the token was created by this thing and it will basically not work anymore. You don't have the information of the token. So what we do is we use the JSON token ID to set the identifier and if we want to this token is not it cannot be used anymore even though it's not expired. So we get the token ID and we create a black list. You can use a cache system to use that to set the time to leave the cache entry will be the same amount of expiration so the cache will do the cleanup for you. You don't need to worry about that. You can also create using the library that I've shown a custom constraint to see is this token ID in my black list or not. How much data can I use in a token? Because you can just put everything in there right? But the problem is your string will be very very big. If you're using a JSON Web token for sessions for example you have a limit on your cookie. It's not that big. So you must be aware that everything that you store there will impact on the size. So be cautious on that. Another question that I often get is how to secure the token. Because it's not an encrypted thing. It's basically you can verify the signature but you cannot say I want to protect the data. Who was on yesterday's talk about Jose? So you saw the idea of JSON Web encryption. The idea is basically you have the same structure as a JSON Web token but for an encrypted object. Instead of three pieces you have five and you have each part saying this is the header for text. This is the encrypted text. You have everything that is needed to know, okay, how should I decrypt this piece of string. And you can also say, okay, encrypt this token. The header will be basically saying, okay, the content type that I have here is a token instead of a token or any other thing. Only people that knows how to decrypt and has access to all the keys that are needed to decrypt the token will be able to consume it. Right. Wow, I was a bit too fast. Okay, so yes, good. Really interesting. To put it in an actual usable example, you've got a web page, on that web page you've got three bits of JavaScript that need to make three Ajax requests to pull data back to show graphs or whatever. For that, when that page loads you need to somehow load in three different tokens for each request, is that correct? It depends. If you want you can create three different tokens. The token will be the identifier for each request, or you can use a single token that has a bigger expiration so you can play around with a single one. It's up to you. In that case, you could just send a singular identifier token and then have additional request-based parameters appended on to say the get request. Would that be correct? Sorry, can you repeat it? If you're making a get request you might, in a traditional get request without JWT, you might for some reason put like user ID etc. I want to get this data for this graph sort of thing. What you're saying is if you have one token, instead of that user ID as the identifier you'd have a token your parameters afterwards to say I want to actually get this data. Is that correct? You can use that way. The benefit of it is that you know when the data changes because you have a signature there. Since the signature, the content was created by a JavaScript client I'm assuming that based on the conversation, the JavaScript must also have the private key in order to generate tokens. If you are creating the keys on the server side and just rendering them then it's fine. You can just use them. So when I have traditional sessions currently and I want to migrate them over to JWT do you have any best practices for that or should I just start over and sign out all users? So I have an existing application with traditional sessions and I want to start JWT. So if you go I will just go back here. If you go to that page you will see all the limitations that we have and that we must understand because as I said the token is not encrypted by default and to encrypt it it requires some processing power. Also to decrypt you will have to have this delay. So maybe encrypting a session data is not really interesting. So the token will be plain. You can use the other limitations is that this library it doesn't create any blacklist. So if the session data changes you are the one to revoke the previews token. So this is the kind of best practice that you need to take into consideration. Like I want to use a stateless or a storage list session but I need to know what all the details that are required in order to not make my application not so safe and secure. So if you care about all this kind of thing things I would say that go with a normal session because if you are storing important data inside of the token you will compromise your security. Okay? Thank you. So I get the impression that you should only use this if you actually need to store some data inside your token because otherwise is it more secure if you have all your data in your database and you just use a nonsense token because then you don't expose any data to the client. You don't have any problem on exposing the expiration date or the date that the token was issued. Yeah and also the user ID is like what the user can do with the user ID. But if you store the user email in a token then my friend you have a problem. Yeah. So good that we are having so many questions. I suppose one of the biggest benefits is that you no longer have to store in your database a massive list of tokens. But one thing that you said that you can create a blacklist. So if one of my users their account is compromised or whatever and they need to blacklist surely I still need to store a list of token IDs in my database so I know which one is the blacklist. Yeah. Yeah. So a trade off if you want to use this kind of token to create an authorization and an authentication flow and you really need to block tokens you have to store something somewhere because how you will know that this token needs to be blacklisted or not. Or if the user is logged on multiple places and you want to blacklist them all so you need to have this at least the IDs of every single token you created but there's a difference on storing just the ID and the whole data. So that's the trade off that you need to do. So I was listening about the signing. So this having the public key to sign the client to sign the request isn't there any type of problem on the if someone steals my signing key that I get compromised. Well the signing key will be the private not the public but if somebody have access to your privately bigger problem than just the token. I was talking about the client signing the request for the server I don't know if I understood the full correctly. Usually you just sign the token at a time that you're issuing it. So if you want to have like we had yesterday the use case where both request and response are signed and they are signed by different issues then you have the private key and the public here and the private key and the public key here and they don't have they're not the same. So when the client creates a new token it says okay I'm creating the token with this ID this key sorry and this key ID represents a public key and the server will validate that token using the client public key and if the client wants to validate the token that was generated on the server side it will use the public key of the server. So nobody knows about the private one. For token in validation this might be a terrible idea please tell me if it is. Would a way to handle that be to store, instead of storing a blacklist to store a whitelist of all the IDs of tokens that have been issued in say something like Redis then they expire when the token is set to expire and then to be able to blacklist something, delete it out of the whitelist. Yeah that works fine as well. The only difference is you probably end up with more tokens on the whitelist than the blacklist but yeah it's perfect. No in that case you wouldn't have that problem because like every token you issue you put the ID in Redis and it will expire in some minutes so you already have the expiration and that's granted on the cache system. So when the token inspires you don't have the whitelist there anymore. The validation will be is my token there? So I'm safe. Instead of is my token blacklist? You are not allowed to use it. So yeah it works fine. It's moving way to store right. No Okay. Yeah and I was able to store the ID with the token in Redis so I could look it up and blacklist it. How would you deal with when tokens expire when they run out of time the expiry day has passed? Would you on the client side on the sort of JavaScript side would you literally mostly just say I don't know when this token expires because it's encrypted inside and I can't find out when it expires but I'll try and use it and then the server comes back to you have to say okay the server comes back and says sorry this token isn't valid anymore and so you make another request or could you say on the server side well this token is good until mid-day tomorrow but it's now 11 o'clock I'll give you a new token that will be good for some more time. Yeah that's up to you because the token is not encoded it's encoded and you have JavaScript libraries to read the token and you can see the expiration date so yeah if the client doesn't want to open a token and to read it it will just say okay the token is invalid or you can do what you're saying okay your request is valid but in five minutes the token will expire which is my new token I created that so you don't need to bother with refreshing the token but when it expires and the client didn't request anything in order to the server to create a new token it will be expired in a period otherwise you're also compromising the security of your API Yeah because if you're using the token as a bearer token it just says here's something that somebody gave me here's this you have to trust that bearer token is was given to the right person and hasn't been shared around so if you then upgrade that token that is a potential security issue because you don't necessarily know they genuinely were given the token Yeah but that happens despite of JSON web tokens with all of you bearer token as well and you can share that token and do new requests Yeah Any other question? Alright Oh here, sorry Do you have somewhere I can go where I want to have a list of libraries you can use together with this? Yep This website Here This one www.io You can just see libraries implemented in all sorts of languages Now there's another question there I think What's the significance of the little three letter acronyms? Sorry? Like the sub and AUD IED Okay Yeah the idea was to have a compact representation so JSON token IED issuer audience, subject issued at, expires and not before Brilliant, thanks There's another one So maybe that may be a question but what's the best practice for example I've logged in in one tab I generated a token and then I open an anonymous tab for example should I detect, wait do you still have a value token and just reuse it or should I create every single time if it's the user identity generates a new token You're basically talking about the two sides right? JavaScript or the client side and the API Yeah the API must receive a request in order to know if the token was used or not so if the token is stored in the local storage the API doesn't know unless we have a request Right? So I'm not sure but I think that on anonymous tab and a normal tab they don't share the local storage area That's idea so for example I generated a new I'm logging in basically on two different computers for example I try and reuse the same token or generate a new one every single login If you always use the same token you have a security issue because someone can just get the token and use it because yeah it's there and it's JavaScript you can just read the token and get it so I wouldn't recommend to reuse the token if you're logging and yeah just create a new token session and make that expire like in few moments like 20 minutes at most so and also have a way to refresh the token All these refreshing mechanisms and granting mechanisms are already covered by OAuth so you can use OAuth creating access tokens with your own web tokens and just use that it's nice because then you can store things into the token and you can read on the client side and present some information if you want No more questions Alright guys Thank you very much