- We will want to publish the package config using the following command: php artisan config:publish tymon/jwt-auth
- JWT’s standard is still not finalized, but there won’t be any major changes there, and the libraries will adapt .
- If I add hashing to your signup, then both signup and signin works as they should.
- Origin ‘http://localhost:8383’ is not allowed access.
- Origin ‘http://localhost’ is not How to fix this hosted on IIS 8.
Cookies are stale. These days there are better solutions for user authentication, which solve the headaches cookies cause with today’s mobile and single-page applications. Toptal engineer Tino Tkalec delivers this demonstration of a Laravel and Angularjs application making use of one of the best authentication methods available today: the JSON Web Token.
@ankosft: JSON Web Token #JWT Tutorial: An Example in Laravel and #AngularJS
With the rising popularity of single page applications, mobile applications, and RESTful API services, the way web developers write back-end code has changed significantly. With technologies like AngularJS and BackboneJS, we are no longer spending much time building markup, instead we are building APIs that our front-end applications consume. Our back-end is more about business logic and data, while presentation logic is moved exclusively to the front-end or mobile applications. These changes have led to new ways of implementing authentication in modern applications.
Authentication is one of the most important parts of any web application. For decades, cookies and server-based authentication were the easiest solution. However, handling authentication in modern Mobile and Single Page Applications can be tricky, and demand a better approach. The best known solutions to authentication problems for APIs are the OAuth 2.0 and the JSON Web Token (JWT).
What is a JSON Web Token?
A JSON Web Token, or JWT, is used to send information that can be verified and trusted by means of a digital signature. It comprises a compact and URL-safe JSON object, which is cryptographically signed to verify its authenticity, and which can also be encrypted if the payload contains sensitive information.
headers or URL query parameters.
A JWT is represented as a sequence of base64url encoded values that are separated by period characters.
JSON Web Token example:
The header contains the metadata for the token and it minimally contains the type of signature and the encryption algorithm.
This JWT Header declares that the encoded object is a JSON Web Token, and that it is signed using the HMAC SHA-256 algorithm.
Once this is base64 encoded, we have the first part of our JWT.
In the context of JWT, a claim can be defined as a statement about an entity (typically, the user), as well as additional meta data about the token itself. The claim contains the information we want to transmit, and that the server can use to properly handle authentication. There are multiple claims we can provide; these include registered claim names, public claim names and private claim names.
These are the claims that are registered in the IANA JSON Web Token Claims registry. These claims are not intended to be mandatory but rather to provide a starting point for a set of useful, interoperable claims.
Public claims need to have collision-resistant names. By making the name a URI or URN naming collisions are avoided for JWTs where the sender and receiver are not part of a closed network.
, and the best practice is to place a file at that location describing the claim so that it can be dereferenced for documentation.
Private claim-names may be used in places where JWTs are only exchanged in a closed environment between known systems, such as inside an enterprise. These are claims that we can define ourselves, like user IDs, user roles, or any other information.
Using claim-names that might have conflicting semantic meanings outside of a closed or private system are subject to collision, so use them with caution.
It is important to note that we want to keep a web token as small as possible, so use only necessary data inside public and private claims.
This example payload has two registered claims, one public claim and two private claims. Once it is base64 encoded, we have the second part of our JWT.
The JWT standard follows the JSON Web Signature (JWS) specification to generate the final signed token. It is generated by combining the encoded JWT Header and the encoded JWT Payload, and signing it using a strong encryption algorithm, such as HMAC SHA-256. The signature’s secret key is held by the server so it will be able to verify existing tokens and sign new ones.
This gives us the final part of our JWT.
It is critical to use TLS/SSL in conjunction with JWT, to prevent man-in-the-middle attacks. In most cases, this will be sufficient to encrypt the JWT payload if it contains sensitive information. However, if we want to add an additional layer of protection, we can encrypt the JWT payload itself using the JSON Web Encryption (JWE) specification.
Of course, if we want to avoid the additional overhead of using JWE, another option is to simply keep sensitive information in our database, and use our token for additional API calls to the server whenever we need to access sensitive data.
Why the need for Web Tokens?
Before we can see all the benefits of using token authentication, we have to look at the way authentication has been done in the past.
How it Works
The browser makes a POST request to the server that contains the user’s identification and password. The server responds with a cookie, which is set on the user’s browser, and includes a session ID to identify the user.
On every subsequent request, the server needs to find that session and deserialize it, because user data is stored on the server.
Token based authentication is stateless, so there is no need to store user information in the session. This gives us the ability to scale our application without worrying where the user has logged in. We can easily use the same token for fetching a secure resource from a domain other than the one we are logged in to.
header. The server then validates the token and, if it’s valid, returns the secure resource to the client.
The authentication server can sign the token using any secure signature method. For example, a symmetric key algorithm such as HMAC SHA-256 can be used if there is a secure channel to share the secret key among all parties. Alternatively, an asymmetric, public-key system, such as RSA, can be used as well, eliminating the need for further key-sharing.
Stateless, easier to scale: The token contains all the information to identify the user, eliminating the need for the session state. If we use a load balancer, we can pass the user to any server, instead of being bound to the same server we logged in on.
Reusability: We can have many separate servers, running on multiple platforms and domains, reusing the same token for authenticating the user. It is easy to build an application that shares permissions with another application.
Security: Since we are not using cookies, we don’t have to protect against cross-site request forgery (CSRF) attacks. We should still encrypt our tokens using JWE if we have to put any sensitive information in them, and transmit our tokens over HTTPS to prevent man-in-the-middle attacks.
Performance: There is no server side lookup to find and deserialize the session on each request. The only thing we have to do is calculate the HMAC SHA-256 to validate the token and parse its content.
In this tutorial I am going to demonstrate how to implement the basic authentication using JSON Web Tokens in two popular web technologies: Laravel 5 for the backend code and AngularJS for the frontend Single Page Application (SPA) example. (You can find the entire demo here, and the source code in this GitHub repository so that you can follow along with the tutorial.)
This JSON web token example will not use any kind of encryption to ensure the confidentiality of the information transmitted in the claims. In practice this is often okay, because TLS/SSL encrypts the request. However, if the token is going to contain sensitive information, such as the user’s social security number, it should also be encrypted using JWE.
We will use Laravel to handle user registration, persisting user data to a database and providing some restricted data that needs authentication for the Angular app to consume. We will create an example API subdomain to simulate Cross-origin resource sharing (CORS) as well.
Installation and Project Bootstrapping
In order to use Laravel, we have to install the Composer package manager on our machine. When developing in Laravel I recommend using the Laravel Homestead pre-packaged “box” of Vagrant. It provides us with a complete development environment regardless of our operating system.
The easiest way to bootstrap our Laravel application is to use a Composer package Laravel Installer.
For any questions about this process please refer to the official Laravel documentation.
, which will configure folder mappings and domains configuration for our local environment.
command in order to create the necessary user tables in our database.
, by Barry vd. Heuvel, for handling CORS.
and update our dependencies.
Finally, we will want to publish the package config using the following command: php artisan config:publish tymon/jwt-auth
function. For example:
We can find out more about this package and all of it’s config settings on Github.
and update our dependencies.
Routing and Handling HTTP Requests
For the sake of brevity, I will put all my code inside the routes.php file that is responsible for Laravel routing and delegating requests to controllers. We would usually create dedicated controllers for handling all our HTTP requests and keep our code modular and clean.
We will load our AngularJS SPA view using
with a username and password, we will try to create a new user and save it to the database. After the user has been created, a JWT is created and returned via JSON response.
with a username and password, we verify that the user exists and returns a JWT via the JSON response.
header or query string needs to provide the JWT for the backend to verify.
. This middleware is used to filter the request and validate the JWT token. If the token is invalid, not present, or expired, the middleware will throw an exception that we can catch.
function we can create HTTP responses based on the thrown exception.
If the user is authenticated and the token is valid, we can safely return the restricted data to the frontend via JSON.
view that will bootstrap the Angular application.
Here is the folder structure of the Angular app:
contains the bare essentials needed to run the application. We’ll use Twitter Bootstrap for styling, along with a custom theme from Bootswatch. To have some visual feedback when making an AJAX call, we’ll use the angular-loading-bar script, which intercepts XHR requests and creates a loading bar. In the header section, we have the following stylesheets:
The footer of our markup contains references to libraries, as well as our custom scripts for Angular modules, controllers and services.
In the production environment, of course, we would minify and combine all our script files and stylesheets in order to improve performance.
variable in the controller’s scope.
which is responsible for configuring all our front end routes.
. Every route corresponds to a partial HTML view. We have also defined two constants that contain URLs for our HTTP requests to the backend.
header containing our JWT if the user is authenticated. We can also use an interceptor to create a global HTTP error handler. Here is an example of our interceptor that injects a token if it’s available in browser’s local storage.
service, which sends HTTP requests to the backend. It then saves the token to local storage, or shows an error message, depending on the response from the backend.
header or query string. If that is not the case, the server will respond with a 401 Unauthorized error status code.
This is a simple service that makes requests to the authentication server as well as the API server for some dummy restricted data. It makes the request, and delegates success and error callbacks to the controller.
JSON Web Tokens work across all popular programming languages and are quickly gaining in popularity. They are backed by companies like Google, Microsoft and Zendesk. Their standard specification by Internet Engineering Task Force (IETF) is still in the draft version and may change slightly in the future.
There is still a lot to cover about JWTs, such with how to handle the security details, and refreshing tokens when they expire, but the examples above should demonstrate the basic usage and, more importantly, advantages of using JSON Web Tokens.