Deploying a web app with JWT authorization in Yandex API Gateway and authentication in Firebase
- Get your cloud ready
- Create a project and set up Google OAuth in Google Cloud
- Set up authentication in Firebase
- Complete setting up your Google resources
- Create an API gateway
- Get the web app files ready
- Deploy Yandex Cloud resources and upload your web app to an Object Storage bucket
- Test the app
- How to delete the resources you created
In this tutorial, you will learn how to implement authentication and authorization with OAuth 2.0
- Firebase external authentication service.
- Simple REST API deployed as an API Gateway.
- Static website deployed in a Yandex Object Storage bucket.
To deploy your web app:
- Get your cloud ready.
- Create a project and set up Google OAuth in Google Cloud.
- Set up authentication in Firebase.
- Complete setting up your Google resources.
- Create an API gateway.
- Get the web app files ready.
- Deploy Yandex Cloud resources and upload your web app to a bucket.
- Test the app.
If you no longer need the resources you created, delete them.
Get your cloud ready
Sign up in Yandex Cloud and create a billing account:
- Navigate to the management console
and log in to Yandex Cloud or register a new account. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one and link a cloud to it.
If you have an active billing account, you can navigate to the cloud page
Learn more about clouds and folders.
Required paid resources
The infrastructure support cost for running a web app includes:
- Fee for data storage in a bucket and data operations (see Object Storage pricing).
- Fee for using the API gateway (see API Gateway pricing).
Create a project and set up Google OAuth in Google Cloud
Set up Google OAuth:
- Log in to the Google Cloud Console
and create a new project. - Go to API & Services → OAuth consent screen, select
External
as the app type, and click Create. - Under OAuth consent screen, enter a name for your app and your email address in the User support email and Developer contact information fields. Click Save and continue.
- Under Scopes, click Add or Remove Scopes and add the
openid
,/auth/userinfo.email
, and/auth/userinfo.profile
scopes. Click Update → Save and continue. - Under Test users, specify your email address. Finish creating your app.
- Go to API & Services → Credentials, click Create credential, and select
OAuth client ID
. SpecifyWeb application
as the app type. - Confirm the app creation and save the
Client ID
andClient secret
.
Set up authentication in Firebase
- Log in to the Firebase Console
and create a new project. - Go to Authentication → Sign-in method → Custom providers and select
OpenID Connect
. - Confirm your selection.
- Enter the provider name as well as the
Client ID
andClient secret
you obtained in the previous step. Fill in the Issuer field (for Google OAuth, specifyhttps://accounts.google.com
). - Save the
Callback URL
and complete the OpenID setup.
Complete setting up your Google resources
Google Console:
- Go to API & Services → Credentials and click the name of the created client.
- Add the Callback URL from Firebase you saved earlier to the Authorized redirect URIs list. Save your changes.
Firebase:
- Go to Project Overview → Project settings.
- Create a web app in the
General
tab. Specify a name for your app and click Register App. - Save the app configuration generated under
firebaseConfig
.
Create an API gateway
-
In the management console
, select the folder where you want to create an API gateway. -
In the list of services, select API Gateway.
-
Click Create API gateway.
-
In the Name field, enter
jwt-api-gw
. -
Under Specification, add the following specification:
openapi: 3.0.0 info: title: Sample API version: 1.0.0 paths: /: get: x-yc-apigateway-integration: type: http url: https://oauth2.googleapis.com/tokeninfo method: GET query: id_token: '{token}' parameters: - name: token in: query required: true schema: type: string security: - OpenIdAuthorizerScheme: [ ] components: securitySchemes: OpenIdAuthorizerScheme: type: openIdConnect x-yc-apigateway-authorizer: type: jwt jwksUri: https://www.googleapis.com/oauth2/v3/certs identitySource: in: query name: token issuers: - https://accounts.google.com requiredClaims: - email
-
Click Create.
If you do not have the Yandex Cloud CLI yet, install and initialize it.
By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the yc config set folder-id <folder_ID>
command. You can also set a different folder for any specific command using the --folder-name
or --folder-id
parameter.
-
Save the following specification to
jwt-auth.yaml
:openapi: 3.0.0 info: title: Sample API version: 1.0.0 paths: /: get: x-yc-apigateway-integration: type: http url: https://oauth2.googleapis.com/tokeninfo method: GET query: id_token: '{token}' parameters: - name: token in: query required: true schema: type: string security: - OpenIdAuthorizerScheme: [ ] components: securitySchemes: OpenIdAuthorizerScheme: type: openIdConnect x-yc-apigateway-authorizer: type: jwt jwksUri: https://www.googleapis.com/oauth2/v3/certs identitySource: in: query name: token issuers: - https://accounts.google.com requiredClaims: - email
-
Run this command:
yc serverless api-gateway create \ --name jwt-api-gw \ --spec=jwt-auth.yaml
Where:
--name
: API gateway name.--spec
: Specification file.
Result:
done (29s) id: d5dug9gkmu187i******** folder_id: b1g55tflru0ek7******** created_at: "2020-06-17T09:20:22.929Z" name: jwt-api-gw status: ACTIVE domain: d5dm1lba80md********.i9******.apigw.yandexcloud.net log_group_id: ckghq1hm19********
If you do not have Terraform yet, install it and configure its Yandex Cloud provider.
-
In the configuration file, define the API gateway properties:
resource "yandex_api_gateway" "jwt-api-gateway" { name = "jwt-api-gw" spec = <<-EOT openapi: 3.0.0 info: title: Sample API version: 1.0.0 paths: /: get: x-yc-apigateway-integration: type: http url: https://oauth2.googleapis.com/tokeninfo method: GET query: id_token: '{token}' parameters: - name: token in: query required: true schema: type: string security: - OpenIdAuthorizerScheme: [ ] components: securitySchemes: OpenIdAuthorizerScheme: type: openIdConnect x-yc-apigateway-authorizer: type: jwt jwksUri: https://www.googleapis.com/oauth2/v3/certs identitySource: in: query name: token issuers: - https://accounts.google.com requiredClaims: - email EOT }
Where:
name
: API gateway name.spec
: API gateway specification.
For more information about
yandex_api_gateway
properties, see this Terraform article . -
Create the resources:
-
In the terminal, go to the directory where you edited the configuration file.
-
Make sure the configuration file is correct using this command:
terraform validate
If the configuration is correct, you will get this message:
Success! The configuration is valid.
-
Run this command:
terraform plan
You will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.
-
Apply the changes:
terraform apply
-
Type
yes
and press Enter to confirm the changes.
-
This will create an API gateway in the specified folder.
To create an API gateway, use the create REST API method for the ApiGateway resource or the ApiGatewayService/Create gRPC API call.
Get the web app files ready
-
Clone the repository
with the app source code:git clone https://github.com/yandex-cloud-examples/yc-serverless-apigw-jwt-authorizer-firebase.git
-
Open the
src/App.js
file using a text editor and specify the following properties:firebaseConfig
: Firebase configuration you saved when completing the Google resource setup.providerId
: ID of the OpenID Connect provider previously created in Firebase, inoidc.<provider_name>
format.apiGwDomain
: Service domain of the API gateway you created earlier.
-
Install Node.js
andnpm
.npm
comes bundled with Node.js. -
In your app folder:
-
Install
react-scripts
in your project and include it underdevDependencies
inpackage.json
:npm install react-scripts --save-dev
-
Run your app build:
npm run build
Result:
File sizes after gzip: 96.05 kB build\static\js\main.de7af71f.js 672 B build\static\css\main.021818e9.css The project was built assuming it is hosted at /. You can control this with the homepage field in your package.json. The build folder is ready to be deployed.
-
Deploy Yandex Cloud resources and upload your web app to an Object Storage bucket
Deploy a static website.
-
Create an Object Storage bucket:
Management consoleCLITerraformAPI- In the management console
, select the folder where you want to create a bucket. - Select Object Storage.
- Click Create bucket.
- On the bucket creation page:
- Enter the bucket name:
bucket-for-tutorial
. - In the Object read access field, select
Public
. - Click Create bucket to complete the operation.
- Enter the bucket name:
If you do not have the Yandex Cloud CLI yet, install and initialize it.
By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the
yc config set folder-id <folder_ID>
command. You can also set a different folder for any specific command using the--folder-name
or--folder-id
parameter.-
Run this command:
yc storage bucket create \ --name bucket-for-tutorial \ --public-read
Where:
--name
: Bucket name.--public-read
: Flag to enable public read access to bucket objects.
Result:
name: bucket-for-tutorial folder_id: b1gmit33******** anonymous_access_flags: ... versioning: VERSIONING_DISABLED acl: {} created_at: "2023-06-08T11:57:49.898024Z"
If you do not have Terraform yet, install it and configure its Yandex Cloud provider.
-
In the configuration file, define the resource properties:
... resource "yandex_iam_service_account" "sa" { name = "<service_account_name>" } resource "yandex_resourcemanager_folder_iam_member" "sa-editor" { folder_id = "<folder_ID>" role = "storage.editor" member = "serviceAccount:${yandex_iam_service_account.sa.id}" } resource "yandex_iam_service_account_static_access_key" "sa-static-key" { service_account_id = yandex_iam_service_account.sa.id description = "static access key for object storage" } resource "yandex_storage_bucket" "test" { access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key bucket = "bucket-for-tutorial" acl = "public-read" } ...
Where:
yandex_iam_service_account
: Description of the service account to create and use the bucket:name
: Service account name.
yandex_storage_bucket
: Bucket description:bucket
: Bucket name.acl
: Bucket access settings.
For more information about
yandex_storage_bucket
properties, see this Terraform article . -
Create the resources:
-
In the terminal, go to the directory where you edited the configuration file.
-
Make sure the configuration file is correct using this command:
terraform validate
If the configuration is correct, you will get this message:
Success! The configuration is valid.
-
Run this command:
terraform plan
You will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.
-
Apply the changes:
terraform apply
-
Type
yes
and press Enter to confirm the changes.
-
This will create a bucket in the specified folder.
To create a bucket, use the create REST API method for the Bucket resource, the BucketService/Create gRPC API call, or the create S3 API method.
- In the management console
-
Upload objects to the Object Storage bucket:
Management console- In the management console
, select the folder where you want to upload your objects. - Select Object Storage.
- Click
bucket-for-tutorial
. - Click Upload and select the objects you previously generated in the
build
folder. - The management console will display all the objects you selected for uploading and prompt you to select a storage class. The bucket configuration determines the default storage class.
- Click Upload.
- Refresh the page.
In the management console, the information about the number of objects and storage space used in the bucket is updated with a few minutes' delay.
- In the management console
-
Set up static website hosting:
Management consoleCLITerraformAPI- In the management console
, go tobucket-for-tutorial
. - In the left-hand panel, select Settings.
- On the Website tab:
- Select
Hosting
. - In the Home page field, specify the absolute path to the website home page file,
index.html
. - In the Error page field, specify the absolute path to the file to display in case of 4xx errors,
error.html
.
- Select
- Click Save.
- Copy your website's URL from the Link field.
If you do not have the Yandex Cloud CLI yet, install and initialize it.
By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the
yc config set folder-id <folder_ID>
command. You can also set a different folder for any specific command using the--folder-name
or--folder-id
parameter.-
Create a file named
setup.json
with hosting settings:{ "index": "index.html", "error": "error404.html" }
Where:
index
: Absolute path to the website home page file.error
: Absolute path to the file the user will see in case of 4xx errors.
-
Run this command:
yc storage bucket update --name bucket-for-tutorial \ --website-settings-from-file setup.json
Where:
--name
: Bucket name.--website-settings-from-file
: Path to the redirect configuration file.
Result:
name: my-bucket folder_id: b1gjs8dck******** default_storage_class: STANDARD versioning: VERSIONING_SUSPENDED max_size: "10737418240" acl: {} created_at: "2022-12-14T08:42:16.273717Z"
If you do not have Terraform yet, install it and configure its Yandex Cloud provider.
To set up a redirect for all requests:
-
Open the Terraform configuration file and add the
redirect_all_requests_to
property to theyandex_storage_bucket
description:... resource "yandex_storage_bucket" "test" { access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_ke bucket = "bucket-for-tutorial" acl = "public-read" website { index_document = "index.html" error_document = "error.html" } } ...
Where:
website
: Website settings:index_document
: Absolute path to the website home page file. This is a required setting.error_document
: Absolute path to the file the user will see in case of4xx
errors. This is an optional setting.
For more information about
yandex_storage_bucket
properties, see this Terraform article . -
Create the resources:
-
In the terminal, go to the directory where you edited the configuration file.
-
Make sure the configuration file is correct using this command:
terraform validate
If the configuration is correct, you will get this message:
Success! The configuration is valid.
-
Run this command:
terraform plan
You will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.
-
Apply the changes:
terraform apply
-
Type
yes
and press Enter to confirm the changes.
-
This will set up hosting in the bucket.
To set up hosting for a static website, use the update REST API method for the Bucket resource, the BucketService/Update gRPC API call, or the upload S3 API method.
- In the management console
-
Add this URL to the list of authorized domains in Firebase:
- Go to Authentication → Settings → Authorized domains.
- Click Add domain and paste the copied URL.
Test the app
- Access the static website via the URL obtained when setting up website hosting and click Call API Gateway without logging in. Make sure the response is
Got error: Request failed with status code 401
. - To log in to the website, click Log in.
- Once logged in, click Call API Gateway again. Make sure your call succeeds and the response contains authenticated user data.
How to delete the resources you created
To stop paying for the resources you created: