Learning Outcomes
- implement local and OAuth authentication in an application
Resources
Lab
Video walk through of this lab.
Setup
Sign into GitLab. Fork this project: https://gitlab.com/langarabrian/auth2
. Remove the fork relationship. Make the project private. Clone YOUR fork of the project in the Google Cloud Shell.
Change to the frontend directory and install the dependencies and build the frontend as follows:
Start a new terminal. Start and run the Feathers backend as follows:
Test the backend by visiting the following URL:
https://8080-dot-...
You should see the shopping list form.
Add a few items to the shopping list. They don’t show on the frontend, but you can see them at the following URL:
http://8080-dot-.../items
Adding Authentication
We are going to modify the application so that it requires the user to authenticate before adding items to the list.
Initial Changes to Backend
In the terminal where the backend is runnig, stop it (Ctrl-C).
Add a new service to the application:
Answer the prompts as follows:
1
2
3
4
What kind of service is it? Mongoose
What is the name of the service? moreitems
Which path should the service be registered on? /moreitems
Does the service require authentication? Yes
Update backend/src/models/moreitems.model.ts
so that it has “description” and “quantity” fields just like the “items” model.
Examine backend/src/services/moreitems/moreitems.hooks.ts
Restart the backend (e.g. PORT=8080 npm run dev
).
Initial Changes to Frontend
Convince yourself that the authentication hook is working by replacing items
with moreitems
in the frontend. On or about line 35 in frontend/src/shoppinglist.js
replace client.service('items')
with client.service('moreitems')
. EVERY TIME YOU MAKE A CHANGE TO THE FRONTEND CODE, you will have to rebuild it by running the following command in the terminal where you last built the frontend:
1
yarn build
Refresh the application in the browser. Open the web console. Try to add a new item. Note the error in the web console.
Create frontend/src/loading.js
as follows:
Create frontend/src/login.js
as follows:
Update frontend/src/application.js
as follows:
Rebuild the frontend. Now if you refresh the application page, you should see the “Loading” message. The next step is to test to see if the user is already logged in during the “Loading” phase. Add this method to the Application
class:
Now if you rebuild and refresh the application page, you should see the placeholder for the login page. The next step is to create a button to login with Google. Update the render
method of the Login
class as follows:
Now if you rebuild and refresh the application page, you should see a “Login with Google” button. If you click it, you will get an error page. The next step is to register our application with Google.
Final Changes to Backend
Go to the GCP Credentials Dashboard.
Click on “CREATE CREDENTIALS | OAuth client ID”. If you haven’t done so already, you will have to “CONFIGURE CONSENT SCREEN”. For “User Type” choose “External” and click on the “CREATE” button. Fill out the “OAuth consent screen” form as follows:
1
2
3
App name: CPSC 2650 Test
User support email: your email
Developer contact information: your email
Click on the “SAVE AND CONTINUE” button.
For “Scopes”, just click on “SAVE AND CONTINUE”.
For “Test users”, add a Google account that you have access to and then click on “SAVE AND CONTINUE”.
On the “Summary” page, click “BACK TO DASHBOARD”.
Now go back to the “Credentials” page and click on Click on “CREATE CREDENTIALS | OAuth client ID”.
Choose “Web application” for application type. For name, choose whatever you want. For authorised redirect URIs, add:
1
https://8080-dot-...appspot.com/oauth/google/callback
(Obviously here, you are going to use your actual web preview domain). Finally click on the “CREATE” button. Enter the “Client ID” and “Client secret” in backend/config/default.json
for google key and secret respectively. You probably don’t want to put the secret directly in the file. Use an environment variable like GOOGLE_OAUTH_SECRET
instead.
You will have to make some other changes to this file because our front and back ends are running on different domains. The value for oauth.redirect needs to be https://8080-dot-...appspot.com
. In the “google” section you also need to set:
1
2
3
"redirect_uri": "https://8080-dot-...appspot.com/oauth/google/callback",
"host": "8080-dot-...appspot.com",
"callback": "/oauth/google/authenticate",
Lastly, we need to make sure the email associated with the Google account is collected when the user logs in. Basically, you can update backend/src/authentication.ts
exactly as for GitLab in the tutorial. Just rename “GitHubStrategy” with “GoogleStrategy” and call authentication.register
for “google” instead of “gitlab”.
Final Changes to Frontend
If you restart the backend and refresh the application page, you should be able to log in with your Google account, but will end up back on the application page, but stuck in the “Loading…” state. The last thing we need to do is detect that the user has authenticated and update the application state.
Add the following in the componentDidMount
method of the Application
class right after the call to client.authenticate()
:
At this point, if you refresh the application page, you should be taken to the shopping list and able to add items.
Assignment
- Implement CI/CD for this project and deploy to Google Cloud Run using the custom domain
shopping.4949NN.xyz
. To get this to work, you will have to add another URI for the Google OAuth Client. Also, modify thebackend/config/production.json
file and update with all the settings configured to the production domain. If you set theNODE_ENV
environment variable toproduction
, the app will pick up the settings from theproduction.json
file. Finally you will have to ensure the other environment variables are available to the running container as well, likeMONGODBURI
andGOOGLE_OAUTH_SECRET
.