How to use Dialogflow Api.ai V2 in ionic App - ionic-framework

I have created a Dialogflow V2 agent and am trying to integrate the same with ionic 4 App.
Steps Followed:
Created a service account and created a JSON key file from google console.
Added the path to ENV variables GOOGLE_APPLICATION_CREDENTIALS
Also ran the below commands for gcloud authentication
gcloud auth application-default login
gcloud auth application-default print-access-token
I can even able to create the access token using the google jwt token
Here the problem is when I use the same access token in my ionic app or even in the postman, am getting 401 unauthorized Invalid access token error.
I have followed the below link to create the Ionic App
https://www.yuribacciarini.com/integrate-dialogflow-chatbot-on-ionic-app/
API CALL:
I am using Native HTTP call
import { HTTP } from '#ionic-native/http/ngx';
private nativeHttp: HTTP
let encUrl = "https://dialogflow.googleapis.com/v2/projects/id/agent/sessions/id:detectIntent";
return from(this.nativeHttp.post("URL", data, headers)
.then(res => {
console.log(res); //Returning [object object]
console.log(JSON.stringify(res)); //Returning data as single string
return res;
}, (error: any) => {
return this.handleError(error);
}));
Response:
In this response data returned as string. I have tried to parse the data and if I take response.data.queryResult or Response.queryResult it shows undefined.
Thanks & Regards,
Janani

The blog you are following is out dated.
To communicate with dialogflow API you need to have access token.
You can follow API v2 guide,
https://chatbotslife.com/dialogflow-v2-rest-api-communication-6cf7ab66ab36

Related

jsonwebtoken verify is giving invalid signature with JWT from keycloak and using jsonwebtoken npm in javascript to verify it

I successfully receive an access token from the following call on keycloak:
http://localhost/auth/realms/myrealm/protocol/openid-connect/token
using
clent_id=myclient
grant_type=password
username=someone
password=mypasswd
client_secret=1a5debfc-63c8-48e8-95cb-b42aa0187310
I can use the token I get from this call on jwt.io, and it verifies correctly with the client secret. However, the following code always gives me an invalid signature error using the same info:
const token = "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJhOWY4NDhhYi05ZTllLTQ0ZDAtYWQ5NC1jN2VhMTBhMDMzOTIifQ.eyJleHAiOjE2Mzg1MDUwOTcsImlhdCI6MTYzODUwNDc5NywianRpIjoiMzYyZmJjNTgtMjM1Mi00YmM4LWE0NmUtMDliMGYzOTgzYzBhIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MC9hdXRoL3JlYWxtcy9teXJlYWxtIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjhlMTM1NTZlLTc2M2MtNGQxOC05OGFlLWY0ZWQ1YWFjODFiZSIsInR5cCI6IkJlYXJlciIsImF6cCI6Im15Y2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6ImYzMWUxM2NiLWUyZDgtNGIxZC04MTQzLTgxMmU3YmE0NTQ5NiIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1teXJlYWxtIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6ImYzMWUxM2NiLWUyZDgtNGIxZC04MTQzLTgxMmU3YmE0NTQ5NiIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiTWlrZSIsInByZWZlcnJlZF91c2VybmFtZSI6InNvbWVvbmUiLCJnaXZlbl9uYW1lIjoiTWlrZSIsImVtYWlsIjoic29tZW9uZUBzb21lZmFrZWRvbWFpbi5jb20ifQ.Ir2qhdGqJzbJPn8S9TzDP2RRmN207pc8y3UrD7cCD5Q";
const secret = "1a5debfc-63c8-48e8-95cb-b42aa0187310";
jsonwebtoken.verify(token, secret, { "algorithms": ["HS256"] });
What am I missing?
I've just been through this myself recently using the jsonwebtoken npm package in a NestJS application. The following solved the problem:
Check the answer here -> https://stackoverflow.com/a/64484150 - this explains where to get the actual client secret, because it is not shown in the Keycloak interface anywhere, the secret can only be retrieved from the Keycloak database via that SQL command
Once you have that you need to change your verify call to be this:
jsonwebtoken.verify(token, Buffer.from(secret, 'base64'), { "algorithms": ["HS256"] });
This is needed because the client secret from the database is base64 encoded.
I used this approach to reduce calls to the Keycloak server's /auth/realms/{{realm-id}}/protocol/openid-connect/userinfo endpoint which adds network overhead, but as mentioned in your comment Mike, that REST API is a valid approach.

GCP IAM REST API Service account key issue

I have been struggling with this particular issue in GCP. I am trying to generate service account keys using Rest API calls outside of GCP. Below is screenshot of the service account along with the roles.
The as far as i can tell the Service account "Service account admin key" is the parent to create, list, etc child permissions.
So when invoking the Rest API call to generate key using this documentation:2
I get the below error
{
"error": {
"code": 403,
"message": "Permission iam.serviceAccountKeys.create is required to perform this operation on service account projects/XXXYYYZZZZZZ/serviceAccounts/XXXYYYYZZZZZZ.iam.gserviceaccount.com.",
"status": "PERMISSION_DENIED"
}
}
What am I missing?!
Updated: Adding additional screenshots of how i setup authorization and testing of Rest API call.
Following your steps, I was able to replicate it without any errors. As an alternative you can generate an access token instead as authentication.
Add an Auth Header. Generate a Bearer Token by using the command below:
gcloud auth application-default print-access-token
Remove the API Key to your URL. This sample URL retrieves:
https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_NAME#PROJECT_ID.iam.gserviceaccount.com/keys
Add keyTypes
USER_MANAGED
Add access token from the gcloud results above.
See sample screenshots below:
You can also refer to this if you want to generate service account keys, just make sure you update your URL, add a JSON body with keyAlgorithm, and use POST instead of GET. For more info, follow this guide.

How to use Workload identity to access ESP in the Google Kubernetes Engine with the Google Cloud .NET SDK?

Background
On the Google Kubernetes Engine we've been using Cloud Endpoints, and the Extensible Service Proxy (v2) for service-to-service authentication.
The services authenticate themselves by including the bearer JWT token in the Authorization header of the HTTP requests.
The identity of the services has been maintained with GCP Service Accounts, and during deployment, the Json Service Account key is mounted to the container at a predefined location, and that location is set as the value of the GOOGLE_APPLICATION_CREDENTIALS env var.
The services are implemented in C# with ASP.NET Core, and to generate the actual JWT token, we use the Google Cloud SDK (https://github.com/googleapis/google-cloud-dotnet, and https://github.com/googleapis/google-api-dotnet-client), where we call the following method:
var credentials = GoogleCredential.GetApplicationDefault();
If the GOOGLE_APPLICATION_CREDENTIALS is correctly set to the path of the Service Account key, then this returns a ServiceAccountCredential object, on which we can call the GetAccessTokenForRequestAsync() method, which returns the actual JWT token.
var jwtToken = await credentials.GetAccessTokenForRequestAsync("https://other-service.example.com/");
var authHeader = $"Bearer {jwtToken}";
This process has been working correctly without any issues.
The situation is that we are in the process of migrating from using the manually maintained Service Account keys to using Workload Identity instead, and I cannot figure out how to correctly use the Google Cloud SDK to generate the necessary JWT tokens in this case.
The problem
When we enable Workload Identity in the container, and don't mount the Service Account key file, nor set the GOOGLE_APPLICATION_CREDENTIALS env var, then the GoogleCredential.GetApplicationDefault() call returns a ComputeCredential instead of a ServiceAccountCredential.
And if we call the GetAccessTokenForRequestAsync() method, that returns a token which is not in the JWT format.
I checked the implementation, and the token seems to be retrieved from the Metadata server, of which the expected response format seems to be the standard OAuth 2.0 model (represented in this model class):
{
"access_token": "foo",
"id_token": "bar",
"token_type": "Bearer",
...
}
And the GetAccessTokenForRequestAsync() method returns the value of access_token. But as far as I understand, that's not a JWT token, and indeed when I tried using it to authenticate against ESP, it responded with
{
"code": 16,
"message": "JWT validation failed: Bad JWT format: Invalid JSON in header",
..
}
As far as I understand, normally the id_token contains the JWT token, which should be accessible via the IdToken property of the TokenResponse object, which is also accessible via the SDK, I tried accessing it like this:
var jwtToken = ((ComputeCredential)creds.UnderlyingCredential).Token.IdToken;
But this returns null, so apparently the metadata server does not return anything in the id_token field.
Question
What would be the correct way to get the JWT token with the .NET Google Cloud SDK for accessing ESP, when using Workload Identity in GKE?
To get an IdToken for the attached service account, you can use GoogleCredential.GetApplicationDefault().GetOidcTokenAsync(...).

How to auto generate new Bearer Token in Postman for GCP Storage

I am trying to upload file from local to GCP bucket through cloud storage Rest API (https://storage.googleapis.com/upload/storage/v1/b) using Postman.
I am using Bearer Token for authorization and running $(gcloud auth print-access-token) command on GCP Shell to generate that token every time.
I need to know, how to auto generate that token from Postman while sending request ?
Is there any way to execute $(gcloud auth print-access-token) every time as a Pre-request Script within Postman ?
Thanks
I'm not very good with postman, but I think you can run pre-request to get token and reuse it in the subsequent request.
If so, you can get inspiration from the gcloud auth print-access-token command by adding the --log-http param to visualize the request performed by the CLI and to reproduce them in Postman.
EDIT 1
If you perform the request, you can see that a post is performed to this URL https://oauth2.googleapis.com/token
To reproduce the call, you can try with a curl
curl -X POST -d "grant_type=refresh_token&client_id=32555940559.apps.googleusercontent.com&client_secret=ZmssLNjJy2998hD4CTg2ejr2&refresh_token=<REFRESH_TOKEN>&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth" https://oauth2.googleapis.com/token
In this call, you need your REFRESH_TOKEN, that you can get here
cat ~/.config/gcloud/legacy_credentials/<YOUR EMAIL>/adc.json
Google Cloud Storage requires authentication as other Google APIs and one of the authentication way is providing bearer token. These bearer tokens are short lived and require regeneration.
So there are 3 ways to generate bearer tokens so you can interact with Google Storage API or other Google APIs using Postman:
Using oauth2l CLI ( Manual Regeneration of new bearer token and update of Authorization header with the new token)
This oauth2l CLI utility allows you to generate bearer tokens which can be pasted into the Authorization header in postman. You can use
Configuration of Postman with OAuth 2 and User Credentials ( Tokens can be managed via the Postman UI and expired ones cleaned up at the click of a button)
Postman can be configured to trigger the OAuth 2 flow and use a generated bearer token in all of the requests. But please make sure that all users have the correct permissions in the Google Cloud Platform project.
You will need to create OAuth 2 credentials in Google Cloud Console:
Go to APIS and Services
Then go to Credentials tab
Click on Create Credentials
Select OAuth Client ID
Fill the fields to create OAuth Client ID ( also add an Authorized redirect URI however this doesn’t need to resolve to anywhere).
The Client ID and Client Secret need to be saved in your machine.
Use Postman’s environment variable functionality to use different credentials per environment/project. In Postman create a new environment for your credentials using the cog icon at the top right.
Configure the variables accordingly: AUTH_CALLBACK_URL , AUTH_URL, AUTH_CLIENT_ID, AUTH_CLIENT_SECRET, AUTH_ACCESS_TOKEN_URL
This variable should be identical to that defined in the OAuth 2 Client ID creation menu and should be one of the following : AUTH_SCOPE
Once defined, these variables can be used in your Authorization tab in Postman. This can be configured at the collection level, the folder level or even the individual request level.
To Regenerate the Token, you can go to Authorization Tab and click on GET NEW ACCESS TOKEN
Configuration of Postman to use a pre-request script and service credentials (The pre-request script automatically regenerates the bearer token when it expires)
For this please check this Tutorial to follow the steps provided there.

Openshift REST API for getting token is not save it into oapi/v1/oauthaccesstokens

I'm using next API for getting oauth token:
/oauth/authorize?client_id=openshift-challenging-client&response_type=token.
I get token, but it is not working then I do requests to some Openshift REST urls like /oapi/v1/nemespaces/namespace/routes.
The token work if I add it into oapi/v1/oauthaccesstokens by hands.
How can I do this automatically ?
Version
OpenShift Master:v1.2.0
Kubernetes Master:v1.2.0-36-g4a3f9c5
The token returned from the /oauth/authorize endpoint is created under /oapi/v1/oauthaccesstokens before being returned. Can you provide the request/response where you obtain the token, and where you attempt to use it against the API?