In the first tutorial of the Headless WordPress series, we have created a way to login with your user account using JWT. This tutorial will show you how you can use the same JWT flow when trying to login users using Google.
To use the Google login, you will need the Google Client ID which can be created using the Google Console. When creating the credentials, you can set the Origin and Redirect URIs to http://localhost:3000
(or any other URL where you host your app).
REST Login Route
To login with Google, we will need to create a custom login route. That route will work like this:
- Verify the Google token,
- Get user information from Google,
- Find user by Google User ID,
- Find user by Google User email if not found by ID,
- Create user if not found,
- Login user using JWT.
We will now create a plugin called Headless (you can call it whatever you want). This plugin will also hold the code from the previous tutorial with the DropZone example where we allowed the user avatar to be saved.
Create a folder headless inside of the plugin folder and create the file headless.php
.
Place yourself inside of this folder through the terminal (command prompt) and use this command to install the Google API client that we will use for verifying the token and getting the user information.
composer require google/apiclient:"^2.0"
This will create a folder vendor
inside of our plugin. Open the file headless.php
and add this to it.
Nothing special is happening in this file. We are including the autoload.php
from the vendor
folder that will load the classes from the Google API Client library that we have installed. We are also including the abstract class REST_API
for creating custom routes and the class REST_APIS
that will load all the custom routes.
Abstract REST_API class
Those classes are not defined yet, but we will do that right now. First, let’s define the abstract class. Create a folder includes
and inside of that folder, another one called abstracts
. Then create a file class-rest-api.php
and add this code.
We are defining this class under the namespace Headless\REST_API
. That way, we can keep our class names short and the namespaces define where our classes belong.
The method add_route
uses the $version
and $path
with the provided $route
and $config
to define an array of routes a class defines. We will use that information later to register those routes.
Login REST Class
Let’s now create the login class that will be used to create login routes. Create a new folder rest-api
inside of the includes
folder. Inside of that folder add a new file class-login.php
. Add the following code to it.
When this class is being constructed, it prepares the google client ID (if not added inside of the class, it will look for a constant HEADLESS_GOOGLE_CLIENT_ID
). You could add a settings page and get that information from there.
We are using the method add_route
to add the google
endpoint. With the help of that method and the attributes $path
and $version
we are creating an endpoint that will look like this: v1/login/google
.
Helper methods
Let’s overview the helper methods here.
find_user_by
This method will check for an existing user by a provided value. For now, we are only looking for the user by google ID, so we are creating a \WP_User_Query
to find a user with the appropriate google ID.
If we don’t provide a defined $key
in the switch, we will use the default WordPress function get_user_by
.
create_user
This method will create a user. Since this method is used mostly by logging users with other platforms such as Google, Facebook and such, we will generate a random username if the username is already taken.
It will also generate a random password if no password is provided. This method returns the user ID (WordPress user ID).
create_token
This method is an exact copy of the method used in the JWT plugin to create the token. This will ensure us to have the same JWT flow as when using regular username/password combination.
Google Login
Let’s now define the method used for logging with google. Add this code to the method login_google
.
Since our Headless WordPress will probably work from a different domain, to allow signing up with Google, we are enabling the CORS with Access-Control-Allow-Origin: *
.
We are then getting the Google_Client
object and verify the token. If the token is verified, we get the user information. The $payload
can then be used to access all the information we need.
We get the Google user ID and try to find an existing user with that ID. If we have found one, we update the google token of the existing user and create a JWT token that will handle the Authentication afterwards in our app.
If we don’t find one, we try to find one with the email from the Google user information. If we find one, we save the google token and the google user ID and then we create the JWT token.
If we don’t find one with the email, we create the user and update it with the information provided by Google. Then we proceed with the same step as above.
Now we need a way to register this route.
REST_APIS class
This class will include our custom route files and register them. Create the file class-rest-apis.php
inside of the includes
folder. Put the following code in it.
We include our new rest-api/class-login.php
and register the routes inside of the method prepare_route
. We instantiate the Login
object and merge the registered routes from that object with all other routes registered inside of this class.
Then we register all of them with the rest namespace headless
. This will mean that our complete google rest route will be: headless/v1/login/google
.
Don’t forget to activate the plugin.
Implementing Google Login inside the JavaScript App
Let’s now go to our JavaScript App that we have created so far in this series Headless WordPress.
Place yourself inside of the main folder of our app through the terminal and install the library react-google-login
with the following command:
npm install react-google-login
Create a folder src/components/login
, this folder will contain our Login components. Create a file LoginGoogle.js
and add this code:
We are importing the component GoogleLogin
and rendering it with our component LoginGoogle
. Our component will get a property setLogin
that will handle the logging into our App.
We pass two methods to the component GoogleLogin
. The method loginWithGoogle
will use the REST API route that we have created. It will pass the token received from the Google to verify it and maybe login our user.
The other method will just console the error.
Now we need to use our new component LoginGoogle
and put it in our Login
component which renders the login form. Open the file src/components/Login.js
and make this changes:
We have defined a new method setLogin
that is binded to this
so we can use this
inside of it. Then we are using the method defined in the App
to login the user. We are importing our component LoginGoogle
and rendering it at the bottom of the form.
That’s it. This will now use the JWT token when logging the user and the rest of our JavaScript App will work as if we were logged in with regular username/password combination.
The Code
The code here contains everything except the node_modules
and vendor
which you need to do it by yourself.
This part is available only to the members. If you want to become a member and support my work go to this link and subscribe: Become a Member
Conclusion
By reusing the JWT logging flow, we can add as many platforms as we want as long as at the end we create the JWT token that the JWT plugin will recognize.
Become a Sponsor
This has been extremely helpful in getting my headless WP backend up and running using the facebook login SDK!! Its very rare to find help on headless wp builds/setups & process, site bookmarked! Great job of explaining and code sharing. Thank you so much for all the help!
Hey Igor and Spencer,
I was looking also for Facebook login implementation.
Would you like to share yours?
How can I setup autoload help me please
Once you install the packages using composer, the autoload.php provided by composer will be enough to autoload classes.
If you have not yet been introduced to composer, you can check their site: https://getcomposer.org/
If you would like create your own custom autoloaders, you can then here is an article from Tom McFarlin about creating autoloaders for WordPress projects: https://tommcfarlin.com/simple-autoloader-for-wordpress/
protected $googleClient = ‘YOUR_GOOGLE_CLIENT_ID’;
should i replace ‘YOUR_GOOGLE_CLIENT_ID’ with id i get from google console ?
Yes, that’s the long google client id. You can see for example in their own code example: https://developers.google.com/identity/sign-in/web/build-button#building_a_button_with_a_custom_graphic how they use the client ID.
But in this code you use the whole part (.apps.googleusercontent.com included).
thank you very much , implemented with React-native / wp backend
and it work like a charm
Hey. Thanks for your tutorial dude. It works on localhost but when on live site it returns 404 route not found. Can you help me?
Hi Wisnu, if I understood correctly, the route is 404? Not page 404?
In case the route is 404 (not found) it might be that the URL to the route is incorrect or some other plugin is maybe blocking that?
Or try updating permalinks (Settings > Permalinks > Save Changes). It should not be related to permalinks but you never know 🙂
Nice man, thanks. but i get invalid-token code when i try to post on post man. i get the id_token from developers.google.com/oauthplayground. i check on jwt.io it contain the userdata from google. but still return invalid-token. how can i resolve that? thanks
In the class-login-2.php file, I do not see the Client.php in the mentioned path ‘/vendor/google/apiclient/src/Google/Client.php’.
Also this path ‘\Firebase\JWT\JWT;’
I have downloaded the google client api from the below links, I checked in both of the zip files.
https://github.com/googleapis/google-api-php-client/releases
google-api-php-client-2.5.0.zip
google-api-php-client-2.5.0_PHP54.zip
can anyone tell how I have to setup Google Client API without composer.
Hi there I’m stuck with this error `Notice: Undefined offset: 0 in /Applications/XAMPP/xamppfiles/htdocs/carstime/wp-includes/rest-api/class-wp-rest-server.php on line 179` I can’t get rid of or understand what I did wrong
Hesham what was the reason for this error?. I am getting the same error. I need to fix this.
How did you solve this?. I am having the same error.
I got fixed the error but now it returns always false whatever within my Android Google id Token that I get, I tried to see if the problem from my Android phone by requesting into https://www.googleapis.com/oauth2/v1/tokeninfo?id_token={idToken} and returns valid but with my custom endpoint always return invalid token or payload: false
Hi Hesham, what do you mean by Android Google ID token? Isn’t that a different thing?
Awesome post! Exactly what I needed for a headless wordpress setup using the JWT Autho for WP REST API plugin and a google login.
Is this going to work with the migration that is taking place? https://developers.google.com/identity/gsi/web/guides/migration
Don’t know really. Haven’t tested it with the new version.
I guess with a few changes it should work fine. Seems like it might be easier now.
Wow, what a tuto ! That’s exactly what I was searching for.
No one explains how to do that. It was realy a good basis to implement google login in worpress in combo with vue.js.
Thank you much and keep up good work.