API Driven Development With Laravel and VueJS (Part 33 of 38)

Public and Private API with Laravel

Dan Pastori

December 28th, 2017

After some careful consideration, I realized that roastandbrew.coffee would be much more powerful if it was partially a public facing, partially user authenticated. Essentially what that means is a user shouldn't have to be authenticated to view some of the data, but if they are authenticated, they can do more such as add cafes, edit cafes, like cafes and do any task that requires user inputs. Allowing un-authenticated users to access data opens up a few security and structural issues that we will walk through. Overall, it's totally worth it. This is one of the few articles I wrote after I had everything configured and even just using roastandbrew.coffee, it's ten-fold more useful.

Let's get started with some of the back end configuration. We will be re-organizing API routes and removing the login route.

Step 1: Organize Routes for Public and Private access

The first thing we will do is organize which routes can be access publicly and which ones need private access.

Let's open up our /routes/api.php file. On top of that file, add a group without the auth:api middleware:

Public API Routes Configuration

/*
  Public API Routes
*/
Route::group(['prefix' => 'v1'], function(){

});

Now we will need to consider which routes need to be 100% protected. This means a 401 if called and not authenticated will be returned if there is no user authenticated who is accessing the app. Most routes should be protected 100% like the /api/v1/cafes/{id}/like route, /api/v1/cafes/{id}/edit route, and POSTing /api/v1/cafes route. Pretty much any route that requires user intervention such as creating entities or grading data based off of a user's credentials. Now there are some routes that need to be hybrid. Like when we get a cafe, if the user is logged in, we will need to see if they liked the cafe. And the user route, if a user is logged in return the user otherwise return an empty JSON object.

Here's how I organized our routes:

Public Routes

  • GET /api/v1/cafes
  • GET /api/v1/cafes/{id} (Get's user like if authenticated, otherwise an empty array)
  • GET/api/v1/brew-methods
  • GET /api/v1/tags
  • GET /api/v1/user

Private Routes

These routes stay under the auth:api middleware:

  • GET /api/v1/cafes/{id}/edit
  • POST /api/v1/cafes
  • PUT /api/v1/cafes/{cafeID}
  • POST /api/v1/cafes/{id}/like
  • DELETE /api/v1/cafes/{id}/like
  • POST /api/v1/cafes/{id}/tags
  • DELETE /api/v1/cafes/{id}/tags/{tagID}

As you can see the routes with verbs other than GET are under the private routes. These are because there are changes being made to the data. We want users to be able to change data but only if they are logged in. With the two route groups we are able to control this access. We still have our requests in place to validate the updating and creating of data so this is an added layer of security.

The final tweak we need to make on our public and private routes is in the app/Http/Controllers/API/UsersController.php file. When we return the user, we should adjust it to grab from the API guard. This is so we grab a user if they are authenticated. This will return null if no user is authenticated.

Our getUser() method should look like this:

User Authentication Method

/*
|-------------------------------------------------------------------------------
| Get User
|-------------------------------------------------------------------------------
| URL:            /api/v1/user
| Method:         GET
| Description:    Gets the authenticated user
*/
public function getUser(){
  return Auth::guard('api')->user();
}

Step 2: Remove Old Login Screen

We will be removing our old log in screen and getting rid of the middleware preventing the app from not being viewable to a non-authenticated user.

First we will open our /routes/web.php file and remove the login route:

Login Route Configuration

Route::get( '/login', 'Web\AppController@getLogin' )
      ->name('login')
      ->middleware('guest');

We will be creating a login modal in the next tutorial on configuring the frontend of the app.

Next we will delete our login screen. The view to be deleted is /resources/views/login.blade.php.

We will also be removing the getLogin method from the /app/Http/Controllers/Web/AppController.php.

Our old login screen is now gone! Like I mentioned earlier we will be implementing a login in the next section in a modal screen.

While we are adjusting the authentication, open the /app/Http/Controllers/Web/AppController.php file and adjust the getLogout() method to redirect to /. Now when the user logs out, they will be redirected to the home screen of the app.

Also in the app/Http/Controllers/Web/AuthenticationController.php file, in the getSocialCallback() method, adjust that redirect to be /. We will take care of redirecting away from the app's front end Layout.vue route in the next tutorial. This way everything is smooth and consistent.

Step 3: Remove Auth Middleware on / Route

All we have to do for this step is in our /routes/web.php file, remove the ->middleware('auth') from the / directory. This will ensure that anyone can access the app. This is what we want for this screen all data is protected through the API and we will block of functions through VueJS in the next tutorial.

Conclusion

This should be all for adjusting our backend to be ready for a public/private API structure. There's a little more work to do on the front end, but we are already making huge progress! Of course, check out the code as you need it here: GitHub - serversideup/roastandbrew: Helping the coffee enthusiast find their next cup of coffee. Also, helping aspiring web and mobile app developers build a single page app and converting it to a mobile hybrid. All tutorials can be found at https://serversideup.net and if you need a hand, let me know in the comment section below!

Want to work together?

Professional developers choose Server Side Up to ship quality applications without surrendering control. Explore our tools and resources or work directly with us.

Join our community

We're a community of 3,000+ members help each other level up our development skills.

Platinum Sponsors

Active Discord Members

We help each other through the challenges and share our knowledge when we learn something cool.

Stars on GitHub

Our community is active and growing.

Newsletter Subscribers

We send periodic updates what we're learning and what new tools are available. No spam. No BS.

Sign up for our newsletter

Be the first to know about our latest releases and product updates.

    Privacy first. No spam. No sharing. Just updates.