The Laravel Schema class provides a database agnostic way of manipulating tables. It works well with all of the databases supported by Laravel, and has a unified API across all of these systems. Creating & Dropping Tables. To create a new database table, the Schema::create method is used. Oct 15, 2017 In this screencast we go through multiple command offered by Laravel-Code-Generator package. We created a very simple 'Music Library' app from the ground up.
Adding authentication to an AngularJS and Laravel application is not the most straight-forward, especially if we take the approach of creating independent front-end and backend applications and connecting them with an API exposed by Laravel. Laravel comes with easy-to-use authentication out of the box, but it is session-based and is therefore most useful for traditional round-trip applications.
For single page applications that rely on an API, a better way to handle authentication is with JSON Web Tokens, or JWTs. Put simply, a JWT (pronounced jot) is a JSON object with three distinct parts that are used together to convey information between two parties. JWTs consist of a header, a payload and a signature which are all encoded. We won't get into full detail about the structure and inner workings of JWTs in this tutorial, but Chris covers it in The Anatomy of a JSON Web Token.
To fully understand how JWTs are used, we have to shift our thinking a bit. Traditional authentication requires that the server store the user's authentication information which is checked every time the user makes a request. This method creates challenges when the application grows and needs to scale up, especially if it is distributed across several different servers. It also becomes problematic when we want to use our API for other purposes, such as for mobile applications. To get a better understanding of the limitations of server-based authentication and how JWTs can help, read The Ins and Outs of Token Based Authentication.
This tutorial will demonstrate how to implement token-based authentication in an AngularJS and Laravel application. To do so, we'll build a simple app that will authenticate users with a login form. If successfully authenticated, the user will be redirected to a view where they can get a list of all users in the database. The focus of the tutorial will be on how we can generate JWTs on the Laravel side, obtain them on the front-end and then send them along with every request to the API.
We'll be using a couple open source packages for this application: jwt-auth for creating JWTs on the Laravel side and Satellizer for handling the AngularJS authentication logic.
Let's create a new Laravel application called jot-bot
. Assuming you have Composer and the Laravel installer setup and ready to go, from the command line:
If everything worked correctly you should have all the Laravel files installed. The next step is to rename .env.example
to .env
so that Laravel can properly pull environment variables for the app.
Dec 18, 2016 Extended Generators for Laravel 5, 6 and 7. If you're familiar with my Laravel 4 Generators, then this is basically the same thing - just upgraded for Laravel 5 & 6. Laravel includes a bunch of generators out of the box, so this package only needs to add a few things, like.
Upcoming Course: Make 20 React Apps!It's possible that the application key doesn't properly generate for you on installation. If that is the case, you can generate a new key:
APP_KEY
within the .env
file will need to be set to this new key. You can also take this opportunity to create a new database for the application and set the database credentials in the .env
file. My .env
file looks like this:
Next, let's fire up the app to make sure everything is working:
If everything is working you should see the Laravel welcome page.
Now that the core Laravel files are installed, let's install jwt-auth. Open composer.json
and update the require
object to include jwt-auth:
Next, let's bring this package in by running an update. From the command line:
We'll now need to update the providers array in config/app.php
with the jwt-auth provider. Open up config/app.php
, find the providers
array located on line 111 and add this to it:
We should also add in the jwt-auth
facades which we can do in config/app.php
. Find the aliases
array and add these facades to it:
We also need to publish the assets for this package. From the command line:
After you run this command you will see a new file in the config
folder called jwt.php
. This file contains settings for jwt-auth, one of which we need to change right away. We need to generate a secret key which we can do from the command line:
You'll see that after running this command we get a new value next to 'secret'
where 'changeme' was before.
We've got everything installed on the Laravel side---now let's take care of the AngularJS dependencies.
There are a number of things that need to happen on the front-end so that we can send a JWT with every request to the Laravel API after our user is authenticated. Namely, we need to keep the JWT in local storage once we retrieve it from the API and also need to add a header to every subsequent request that contains the token. We could write the appropriate JavaScript to accomplish this on our own, but a package has already been created that does a great job of it. Instead of spending extra effort, let's make use of Satellizer.
Let's use npm
to install our front-end dependencies. From the command line:
Laravel comes with a migration for a users
table out of the box and this is the only one we'll need for the tutorial. Let's run the migrations so that this table gets created in the database and then seed it with some test data. From the command line:
For seeding, we'll put the array of users and the logic to insert them into the database right within DatabaseSeeder.php
, but you can also create a separate seeder file and call it from that file if you like.
In this seeder we are creating an array of users and then looping through them to add them to the database. This file relies on us using AppUser
which is the User
model that also ships with Laravel. As we loop through the users we call create
on each to add that record to the database. With this in place, we just need to run the seeder.
Once we've confirmed that the database has been seeded properly, let's get the API setup in routes.php
.
We've done a couple things here---first, we've changed the starting route to load a view that we'll create later called index
instead of welcome
. Next, we've created a route group that is prefixed with api
and that currently serves a resource
called authenticate
. We only really want the index
method of this resource controller which we indicate with the third argument. We'll also need a custom method called authenticate
on this controller which handles generating and returning a JWT.
Now we need to create a resource controller called AuthenticateController
. From the command line:
If that runs successfully you should now see AuthenticateController.php
in app/Http/Controllers
.
We're going to need to use
some pieces of the JWTAuth package in this controller.
The try
block in the authenticate
method attempts to produce a token using the JWTAuth
facade with the user's credentials. If something goes wrong with that, the method will return a 401
and say the credentials are invalid. In other cases where an exception is thrown, it will return a 500
indicating an internal server error and saying that something went wrong. If we are able to get past that then we can return a token. Returning it with compact('token')
puts the object on a key called token
which will come in handy when we read it with Satellizer.
We'll use this controller to show data for all users as well, but let's first test out the API.
By default, Laravel has CSRF token verification turned on, but since we're using JWTs in a stateless manner now, we don't really need CSRF tokens. We can turn this default behavior off by commenting out the VerifyCsrfToken
middleware in Kernel.php
.
We're also eventually going to need to use the middleware that jwt-auth provides. We can set that up in the routeMiddleware
array in Kernel.php
as well.
Now that VerifyCsrfToken
is turned off, let's check the API with Postman.
If we send a POST
request to localhost:8000/api/authenticate
with the credentials for one of our users as URL parameters, we can see that we get a token returned.
Now that we're successfully getting a token, let's put it to use and setup our index
method in the controller to return the data for all users if a token is present.
We're going to return the data for all of the users in the database, but only if there is a token passed along with the request. We can make this happen by protecting our API with the middleware that comes with jwt-auth.
Let's add some logic to show all of the users if the token sent along with the request is valid.
Here we are saying we want the jwt-auth middleware to be applied to everything in the controller except the authenticate
method (we don't want to block the user from retrieving their token) and we have the index
method returning a list of all users.
If we try making a GET
request to localhost:8000/api/authenticate
without a JWT in as a header or URL parameter, we get a 400
error that says no token was provided.
If, however, we copy and paste the JWT we retrieved earlier as a URL parameter with the key of token
, we get all the user data returned to us.
The jwt-auth middleware checks for the presence of the token and let's the request through if it is there and is valid, but rejects the request if it is not.
Just to prove that the middleware is doing its job, let's try removing a character from the token to invalidate it. We can see that the call we then make to the index
method gets denied and we can't see the users list.
Now that the API is setup and the middleware is functioning properly we can create the front-end of our app.
We'll need to setup our initial view in an index.php
file because this is what our Laravel routes.php
file is setup to return when the user hits the main /
route.
In the index.php
file we have included all of the application dependency scripts that we installed earlier and have also put references in for the application scripts that we've yet to create. Since we're using UI Router we are serving a ui-view
in the middle of the page which is what will be used to handle our different states.
Next, let's create our main app.js
file.
Here we are loading the ui.router
and satellizer
modules and setting up some configuration for them. Satellizer gives us an $authProvider
which can be used to configure its settings. In particular, we want to specify that when using Satellizer to login, the HTTP requests that get made to retrieve the JWT from the API should go to api/authenticate
.
We also use $stateProvider
to setup configuration for the two states that we'll be using: auth
and users
.
We'll now need to create views for the auth
and users
states and controllers to handle their behavior.
In our AuthController
we are injecting $auth
which is a service provided by Satellizer for communicating with the API and also $state
so that we can handle redirects.
We've got one method in this controller---login
---which is responsible for using the $auth
service to make a call to the API to retrieve the user's JWT. We setup our credentials object to contain an email address and password which we'll get from the form fields in the view and then pass them to the login
method on the $auth
service. If the token is successfully retrieved we are redirected to the users
state.
So what does the $auth
service do exactly? If we dig into the Satellizer source we can see what's happening when the login
method is called on line 422.
We can see here that this method makes an $http.post
call to the login URL that we specified in our config block in app.js
and, if successful, sets the returned token in local storage.
Now let's setup the template for the login page.
In this view we setup two form fields---one for the user's email address and the other for their password. Next we call the login
method in our AuthController
to submit the data.
Serial keys can contain uppercase and/or lowercase charactes and/or numbers. Hp p420i quickspecs. Generate up to 2 million serial keys in one turn (1 million with 32 bit version of SKG). INNO and NSIS scripts are also supported.Features: Generate serial keys using custom number of columns and characters per column.
We can now try logging in to see if we get our token set in local storage.
Password: secret
If everything worked out we should now see the token saved in local storage.
We will also have been redirected to the users
state which is what we want; however, we don't yet have a view or controller setup to handle this state. Let's put that in now.
This controller has one method, getUsers
, which makes an $http.get
request to the API to fetch the data for all users. If the call is successful, the users data is placed on the vm.users
key. If not, the error message that gets returned is placed on the vm.error
key. Now let's reflect this data in a view:
When this state is first loaded there won't be any data displayed because we have set it up so that the data is fetched when the Get Users!
button is clicked. Since we have our token saved in local storage, we should be able to get a list of the users back when we click this button.
You might be wondering how we are successfully getting data back when we haven't done anything to send the JWT along with our $http
request. Satellizer is taking care of this for us behind the scenes and is including the token as a header. We can see this if we open up the network tab in developer tools and inspect the request that was just sent.
An Authorization
header gets added to the request with a value of Bearer
. The token from the header is parsed by the jwt-auth middleware on the backend and our request is granted if it is valid.
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
To prove that the request won't be successful if the token isn't present, let's try deleting it from local storage. In developer tools, right-click the token and choose delete, then refresh the page.
As you can see, the error condition is hit in this case and we aren't able to get the user data.
In this tutorial we have seen how we can authenticate our AngularJS and Laravel applications with JSON Web Tokens. We secured our API with jwt-auth and setup middleware so that the user data only gets returned if the token is present. We then used Satellizer to set the user's token in local storage and to add it to the Authorization
header of every subsequent request to the API.
There are a few other important things necessary for a full authentication setup that we didn't look at in this tutorial, including:
$rootScope
so that we can pass their information around from state to stateTo dive into these additional authentication aspects, head over to my site where we'll continue Token-Based Authentication for AngularJS and Laravel Apps!
If you’d like to get more AngularJS and Laravel tutorials, feel free to head over to my website and signup for my mailing list. You should follow me on Twitter---I'd love to hear about what you're working on!
Like this article?Follow @ryanchenkie on Twitter