Implementing a https enabled redirect service using Firebase
More and more web-traffic is moving to https instead of http protocol. Because users are using a modern browser that defaults to https or a browser extension like Https-By-Default . A great development from a security- and privacy perspective. But with some side effects as it pointed out that the redirect service offered by our hosting provider does not fully support https which causes a security warning.
Although valid commercial solutions are available this fully triggered my (somewhat rusty) not invented here syndrome. Performing the redirect sounds like a suitable functionality for a simple cloud function. With the additional requirement that it should be able to host the cloud function on the (sub)domain(s) we want to use for our redirects.
This blog post will describe the simple steps to develop a cloud function using Firebase Functions and expose it through Firebase Hosting over https using a valid certificate.
Prepare your Firebase Project
Install the Firebase CLI using the instructions provided at: https://firebase.google.com/docs/cli/#install_the_firebase_cli.
Authenticate your Firebase CLI using your Google or GSuite account.
firebase login
Create a Firebase / Google Cloud project using the CLI and specifying the project ID. Hit enter to accept your project ID as project name.
firebase projects:create example-redirect-service
? What would you like to call your project? (defaults to your project ID)
Executing this command will lead to the following output:
β Creating Google Cloud Platform project
β Adding Firebase resources to Google Cloud Platform project
πππ Your Firebase project is ready! πππ
Project information:
- Project ID: example-redirect-service
- Project Name: example-redirect-service
Firebase console is available at
https://console.firebase.google.com/project/example-redirect-service/overview
Create a folder on your local machine for this project and change into this folder.
mkdir example-redirect-service
cd example-redirect-service
Initialize your Firebase Hosting project.
firebase init hosting
Setup your project by providing the following answers:
-
Use an existing project
-
example-redirect-service (example-redirect-service)
-
The default public directory? (public)
-
Donβt configure as a single-page app (N)
-
Skip setting up automatic builds using GitHub (N)
After initialization your folders contains:
-
The firebase configuration file: firebase.json
-
A public folder containing an index.html file and a 404.html file
Lets deploy the generated app.
firebase deploy --only hosting
After successful deployment access the Hosting URL provided in the outut, in our case: https://example-redirect-service.web.app. This should serve you the contents of the index.html.
Implement the redirect function using Firebase Functions
The next step is to add Firebase Functions to our project.
firebase init functions
Setup your functions by providing the following answers:
-
Select TypeScript as language (Typescript)
-
Add ESLint support (Y)
-
Install the dependencies now using NPM (Y)
Open the index.ts within the functions/src folder. Remove the current contents and implement the redirect functionality.
import * as functions from 'firebase-functions';
export const redirect = functions.https.onRequest((request, response) => {
functions.logger.info("Redirect for request: ",
request.headers["x-forwarded-proto"],
request.headers["x-forwarded-host"],
request.url
);
response.redirect(301, "https://jdriven.com/blog/");
});
The function will log the details for the incoming request and redirect all traffic to https://jdriven.com/blog/ using the http status 301 Moved Permanently.
Note: You can alter this code to do multiple and/or more advanced redirects based on hostname, path etc.. Have fun!
Deploy the function:
firebase deploy --only functions
Note: When you get an error that the billing account is not found, please add a billing account for your project using the Google Cloud Console: https://console.cloud.google.com/billing/.
Note 2: When you get the following error "Error: HTTP Error: 403, Unknown Error" re-run the deploy command and it should work the second time.
After a few minutes the function will be deployed. The output shows the Function URL. In our case: https://us-central1-example-redirect-service.cloudfunctions.net/redirect.
Access this url in your browser and verify that the redirect is working and you are redirected to this famous JDriven blog.
Configure Firebase Hosting to expose our function
To be able to use this redirect service on our own (sub)domain we have to expose our function through Firebase Hosting and configure our own (sub)domain.
Open the Firebase configuration file firebase.json and add the rewrite configuration for the redirect function.
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [ {
"source": "**",
"function": "redirect"
} ]
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
}
Adding this rewrite configuration will pass all requests that donβt match a resource in our public folder to our redirect function. The next step is to remove the generated index.html from the public folder to allow redirects for requests to our domains root.
Now itβs time to redeploy both our functions and hosting.
firebase deploy --only functions,hosting
After successful deployment access the Hosting URL you used previously: https://example-redirect-service.web.app. This should redirect you to the JDriven Blog.
After executing the request you can view the Firebase Functions log using the following command.
firebase functions:log
2020-10-27T08:57:40.861Z I redirect: Redirect for request: https example-redirect-service.web.app /
2020-10-27T08:57:40.938089351Z D redirect: Function execution took 97 ms, finished with status code: 301
Adding your own (sub)domain to Firebase Hosting
If we want to perform redirects for our own (sub)domain weβll have to add our own domain to Firebase Hosting. After adding the domain Firebase will also generate a valid SSL certificate and expose our redirect services over https.
Add the (sub)domain following the steps below:
-
Open the Firebase console in your browser: https://console.firebase.google.com
-
Select your project
-
Click on hosting
-
Click on Add Custom Domain
-
Follow the steps in the wizard and
-
Add a TXT record to your DNS entries to verify the domain ownership
-
Add the A records to the IP addresses the wizard shows
-
Remove any old A records if they are available
-
Note: It might take up to 24 hours before the SSL certificate for your custom domain is populated
The sample source code is available: https://bitbucket.org/jdriven/example-redirect-service/src/master/