My application need feature like login with Google to get access token for using Google rest API.
Here is configuration of my providers in Manifest:
modules:
jira:globalPage:
- key: google-provider-hello-world-page
resource: main
resolver:
function: resolver
title: google-provider
function:
- key: resolver
handler: index.handler
providers:
auth:
- google
resources:
- key: main
path: static/hello-world/build
tunnel:
port: 3000
providers:
auth:
- key: google
name: Google
type: oauth2
clientId: <client key>
remotes:
- google-apis
bearerMethod: authorization-header
scopes:
- https://www.googleapis.com/auth/userinfo.email
actions:
authorization:
remote: google-account
path: /o/oauth2/v2/auth
exchange:
remote: google-oauth
path: /token
resolvers:
accessToken: access_token
revokeToken:
remote: google-oauth
path: /revoke
retrieveProfile:
remote: google-apis
path: /userinfo/v2/me
resolvers:
id: id
displayName: email
avatarUrl: picture
remotes:
- key: google-apis
baseUrl: https://www.googleapis.com
- key: google-account
baseUrl: https://accounts.google.com
- key: google-oauth
baseUrl: https://oauth2.googleapis.com
permissions:
content:
styles:
- 'unsafe-inline'
scripts:
- 'unsafe-inline'
external:
styles:
- '*'
frames:
- '*'
scripts:
- '*'
images:
- '*'
fetch:
client:
- '*'
backend:
- 'https://www.googleapis.com'
- 'https://oauth2.googleapis.com'
- 'https://accounts.google.com'
app:
id: ari:cloud:ecosystem::app/5129f53c-5d50-4432-9315-91944482b33d
runtime:
name: nodejs18.x
here is my index.ts:
import API from '@forge/api';
import Resolver from '@forge/resolver';
const resolver = new Resolver();
resolver.define('getText', (req) => {
console.log(req);
return 'Hello world!';
}).define("process-provider-google", async (req) => {
try{
console.info("1")
const google = API.asUser().withProvider('google', 'google-apis')
console.info("2")
const isHasCredentials = await google.hasCredentials();
console.info("3")
console.info(JSON.stringify(isHasCredentials))
if (!isHasCredentials) {
console.info("-- start request credentials --")
await google.requestCredentials()
console.info("-- request credentials done --")
}
const response = await google.fetch('/userinfo/v2/me');
if (response.ok) {
return response.json()
}
return {
status: response.status,
statusText: response.statusText,
text: await response.text(),
}
}catch(exception){
console.error(exception);
}
});
export const handler = resolver.getDefinitions();
my app.js in static project is:
import React, { useState, useEffect } from 'react';
import { GoogleLogin, googleLogout, useGoogleLogin } from '@react-oauth/google';
import axios from 'axios';
import {invoke} from "@forge/bridge"
function App() {
const [ data, setData ] = useState(undefined);
useEffect(() => {
const googleProvider = async () => {
const response = await invoke("process-provider-google")
setData(response)
}
googleProvider();
},[])
return (
<div>
<p>test</p>
{data ? <p>{JSON.stringify(data)}</p> : <p>{}</p>}
</div>
);
}
export default App;
I already run forge providers configure
and set Client secret.
When run forge tunnel
and request to add-on, it have error logs
[NEEDS_AUTHENTICATION_ERR: Authentication Required] {
serviceKey: āgoogle2ā,
options: undefined,
status: 401
}
When code hit await google.requestCredentials()
in index.ts it throw error.
Thanks for helping me.