Public and Private API with Laravel
Part 34 of 48 in API Driven Development With Laravel and VueJSAfter 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
*/
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:
/*
|-------------------------------------------------------------------------------
| 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:
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!