无法通过使用节点js的JWT凭证获得Google AI预测结果

问题描述 投票:0回答:1

我计划使用服务帐户获得AI预测结果,并将云功能部署到Firebase项目。当试图获得预测结果时>

https://ml.googleapis.com/v1/projects/projectid/models/category:predict

使用accesstoken JWT,结果是

{ StatusCodeError: 403 - {"error":{"code":403,"message":"Access to model denied.","status":"PERMISSION_DENIED"}}

已确认我正在使用的服务帐户已添加到ML项目中。

任何想法如何使用服务帐户在Firebase函数中获得ML结果?或其他方法?

这里是代码(我仍然是NodeJS的新手)

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const admin = require('firebase-admin');
const request = require("request");
const requestProm = require("request-promise");

const functions = require('firebase-functions');
const { GoogleAuth } = require('google-auth-library');

admin.initializeApp();


var reportFld, reportNarTr, reportTitTr;
var input, input2, input3;
var result, predictedHaz, predictedSig, predictedRep, setDoc
var getAccessTokenId

getAccessTokenId = async function main() {
    const auth = new GoogleAuth({        
        scopes: 'https://www.googleapis.com/auth/cloud-platform'
    });
    const client = await auth.getClient();
    const projectId = await auth.getProjectId();


    const accessTokenId = await auth.getAccessToken();

    return accessTokenId
}

exports.newReport = functions.firestore
    .document('/users/{usersId}')
    .onCreate((change, context) => {

        const db = admin.firestore();

        const interDoc = db.collection('users').doc(context.params.usersId);
        interDoc.get().then(doc => {
            if (!doc.exists) {
                console.log('No such document!');
            } else {

                var getPrediction
                getPrediction = async function main2() {                    
                    reportFld = doc.data();
                    reportNarTr = JSON.stringify(reportFld.narrative);
                    reportTitTr = JSON.stringify(reportFld.title);
                    reportNumTr = context.params.usersId;

                    input = {
                        instances: [
                            [reportNumTr, reportTitTr, reportNarTr]
                        ]
                    };

                    var accessToken = await getAccessTokenId();


                    var endpointhazCat = 'https://ml.googleapis.com/v1/projects/projectid/models/hazcat:predict?access_token=' + accessToken;
                    var endpointsigCat = 'https://ml.googleapis.com/v1/projects/projectid/models/sig:predict?access_token=' + accessToken;
                    var endpointrepCat = 'https://ml.googleapis.com/v1/projects/projectid/models/type:predict?access_token=' + accessToken;
                    var options1 = {
                        method: 'POST',
                        uri: endpointhazCat,
                        body: input,
                        json: true // Automatically stringifies the body to JSON
                    };

                    var options2 = {
                        method: 'POST',
                        uri: endpointsigCat,
                        body: input,
                        json: true // Automatically stringifies the body to JSON
                    };

                    var options3 = {
                        method: 'POST',
                        uri: endpointrepCat,
                        body: input,
                        json: true // Automatically stringifies the body to JSON
                    };

                    requestProm.post(options1)
                        .then(function (response) {
                            result = response['predictions'];
                            switch (parseInt(result)) {
                                case 0:
                                    predictedHaz = 'A';
                                    break;

                                case 1:
                                    predictedHaz = 'B';
                                    break;

                                case 2:
                                    predictedHaz = 'C';
                                    break;

                                case 3:
                                    predictedHaz = 'D';
                                    break;

                                case 4:
                                    predictedHaz = 'E';
                                    break;

                                case 5:
                                    predictedHaz = 'F';
                                    break;

                                case 6:
                                    predictedHaz = 'G';
                                    break;

                                default:
                                    predictedHaz = 'error';

                            }

                            const predictedHazData = {
                                HazardCategory: predictedHaz,
                            };

                            setDoc = db.collection('users').doc(context.params.usersId).update(predictedHazData);

                            console.log(response);
                            return true
                        })

                        .catch(function (err) {
                            console.log('Failed', err)
                        });


                    requestProm.post(options2)
                        .then(function (response) {
                            result = response['predictions'];
                            if (parseInt(result) > -4) {
                                predictedSig = 'Sig';
                            } else predictedSig = 'Insig'


                            const predictedSigData = {
                                SignifanceCategory: predictedSig,
                            };

                            setDoc = db.collection('users').doc(context.params.usersId).update(predictedSigData);

                            console.log(response);
                            return true
                        })

                        .catch(function (err) {
                            console.log('Failed', err)
                        });


                    requestProm.post(options3)
                        .then(function (response) {
                            result = response['predictions'];
                            if (parseInt(result) === 1) {
                                predictedRep = 'Inc';
                            } else predictedRep = 'Haz'


                            const predictedRepData = {
                                ReportCategory: predictedRep,
                            };

                            setDoc = db.collection('users').doc(context.params.usersId).update(predictedRepData);

                            console.log(response);
                            return true
                        })

                        .catch(function (err) {
                            console.log('Failed', err)
                        });

                    return true
                }

                getPrediction().catch(console.error);
            } return null
        })
            .catch(err => {
                console.log('Error getting document', err);
            });

        return true;
    });

添加了一些详细信息:

这些是服务帐户权限:

ml.jobs.cancel
ml.jobs.create
ml.jobs.get
ml.jobs.getIamPolicy
ml.jobs.list
ml.jobs.update
ml.locations.get
ml.locations.list
ml.models.create
ml.models.delete
ml.models.get
ml.models.getIamPolicy
ml.models.list
ml.models.predict
ml.models.update
ml.operations.cancel
ml.operations.get
ml.operations.list
ml.projects.getConfig
ml.studies.create
ml.studies.delete
ml.studies.get
ml.studies.getIamPolicy
ml.studies.list
ml.trials.create
ml.trials.delete
ml.trials.get
ml.trials.list
ml.trials.update
ml.versions.create
ml.versions.delete
ml.versions.get
ml.versions.list
ml.versions.predict
ml.versions.update 
resourcemanager.projects.get

我尝试在调试控制台上使用其他节点库'googleapis':

google.auth.getApplicationDefault((err, authClient, projectId) => {

  if (err) {

    console.log('Authentication failed because of ', err);
    res.status(401).send('Authentication failed');

  } else {

    // create the full model name which includes the project ID
    const modelName = 'projects/ml-project-id/models/hazcat';
    const mlRequestJson = {
      'auth': authClient,
      'name': modelName,
      'resource': { instances: [['RepNum', 'RepTit', 'RepNar']]
          }
    }

    ml.projects.predict(mlRequestJson, (err, result) => {
      if (err) {
          console.log(err);          
      } else {
          console.log(result.data.predictions[0]);
      }
  }); 
  }
});

结果是:

3

并部署到firebase:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

const admin = require('firebase-admin');
const request = require("request");
const requestProm = require("request-promise");
const functions = require('firebase-functions');
const { GoogleAuth } = require('google-auth-library');
const { google } = require('googleapis');
const ml = google.ml('v1');

admin.initializeApp();


var reportFld, reportNarTr, reportTitTr, reportNumTr, reportTitStr, reportNarStr;
var input, input2, input3;
var result, predictedHaz, predictedSig, predictedRep, setDoc


exports.predictReport = functions.firestore
    .document('/users/{usersId}')
    .onCreate((change, context) => {

        const db = admin.firestore();

        const interDoc = db.collection('users').doc(context.params.usersId);
        interDoc.get().then(doc => {
            if (!doc.exists) {
                console.log('No such document!');
            } else {                
                reportFld = doc.data();
                reportNarTr = JSON.stringify(reportFld.narrative);
                reportTitTr = JSON.stringify(reportFld.title);
                reportNumTr = context.params.usersId;

                input = {
                    instances: [
                        [reportNumTr, reportTitTr, reportNarTr]
                    ]
                };

                var result1, result2, result3

                google.auth.getApplicationDefault((err, authClient, projectId) => {

                    if (err) {

                        console.log('Authentication failed because of ', err);
                        res.status(401).send('Authentication failed');

                    } else {

                        const modelName = 'projects/ml-project-id/models/hazcat';
                        const modelName2 = 'projects/ml-project-id/models/sig';
                        const modelName3 = 'projects/ml-project-id/models/type';

                        const mlRequestJson1 = {
                            'auth': authClient,
                            'name': modelName,
                            'resource': input
                        }

                        const mlRequestJson2 = {
                            'auth': authClient,
                            'name': modelName2,
                            'resource': input
                        }

                        const mlRequestJson3 = {
                            'auth': authClient,
                            'name': modelName3,
                            'resource': input
                        }
                        var result1, result2, result3
                        ml.projects.predict(mlRequestJson1, (err, result) => {
                            if (err) {
                                console.log(err);

                            } else {

                                console.log(result.data.predictions[0]);
                                result1 = result.data.predictions[0];
                                switch (parseInt(result1)) {
                                    case 0:
                                        predictedHaz = 'A';
                                        break;

                                    case 1:
                                        predictedHaz = 'B';
                                        break;

                                    case 2:
                                        predictedHaz = 'C';
                                        break;

                                    case 3:
                                        predictedHaz = 'D';
                                        break;

                                    case 4:
                                        predictedHaz = 'E';
                                        break;

                                    case 5:
                                        predictedHaz = 'F';
                                        break;

                                    case 6:
                                        predictedHaz = 'G';
                                        break;

                                    default:
                                        predictedHaz = 'error';

                                }

                                const predictedHazData = {
                                    HazardCategory: predictedHaz,
                                };
                                setDoc = db.collection('users').doc(context.params.usersId).update(predictedHazData);
                            }
                        }); // endof predict1

                        ml.projects.predict(mlRequestJson2, (err, result) => {
                            if (err) {
                                console.log(err);                                
                            } else {                                
                                console.log(result.data.predictions[0]);
                                result2 = result.data.predictions[0];

                                if (parseInt(result2) > -4) {
                                    predictedSig = 'Sig';
                                } else predictedSig = 'Insig'


                                const predictedSigData = {
                                    SignifanceCategory: predictedSig,
                                };

                                setDoc = db.collection('users').doc(context.params.usersId).update(predictedSigData);

                            }
                        });// endof predict2

                        ml.projects.predict(mlRequestJson3, (err, result) => {
                            if (err) {
                                console.log(err);

                            } else {                                
                                console.log(result.data.predictions[0]);
                                result3 = result.data.predictions[0];

                                if (parseInt(result3) === 1) {
                                    predictedRep = 'Inc';
                                } else predictedRep = 'Haz'


                                const predictedRepData = {
                                    ReportCategory: predictedRep,
                                };

                                setDoc = db.collection('users').doc(context.params.usersId).update(predictedRepData);
                            }
                        });// endof predict3
                    }//endof else getappdefault
                });//endof getappdefault
            } return true
        })//endof getdocument
            .catch(err => {
                console.log('Error getting document', err);
            });
        return true;
    });//endof onCreate

结果是

Authentication failed because of  Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
    at AuthPlus.getApplicationDefaultAsync (/srv/node_modules/googleapis-common/node_modules/google-auth-library/build/src/auth/googleauth.js:156:23)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7) 

添加了详细信息(更新2)

我已经使用了指向服务帐户json文件的密钥文件。
getAccessTokenId = async function main() {    
    const auth = new GoogleAuth({
        keyFile: 'projectid.json',
        scopes: 'https://www.googleapis.com/auth/cloud-platform'
    });    
    const client = await auth.getClient();
    const projectId = await auth.getProjectId();
    const accessTokenId = await auth.getAccessToken();    
    return accessTokenId
}

像这样获得访问令牌

ya29.c.xxxx

并且该权限被拒绝

Failed { StatusCodeError: 403 - {"error":{"code":403,"message":"Access to model denied.","status":"PERMISSION_DENIED"}}

添加了详细信息(更新3)

我正在使用我的个人凭据在云功能内部输入ML模型作品
getAccessTokenId = async function main() {    
        const auth = new GoogleAuth({        
        keyFile: 'application_default_credentials.json',
        scopes: 'https://www.googleapis.com/auth/cloud-platform'
    });
    const client = await auth.getClient();
    const projectId = await auth.getProjectId();
    const accessTokenId = await auth.getAccessToken();
    return accessTokenId
}

获取结果

{ predictions: [ 3 ] }

我还在服务帐户上添加了服务帐户令牌创建者角色,但仍无法使用服务帐户访问ML模型。>

iam.serviceAccountKeys.create
iam.serviceAccountKeys.delete
iam.serviceAccountKeys.get
iam.serviceAccountKeys.list

但很好奇为什么没有这些

iam.serviceAccounts.getAccessToken
iam.serviceAccounts.signBlob
iam.serviceAccounts.signJwt
iam.serviceAccounts.implicitDelegation
iam.serviceAccounts.getOpenIdToken

我计划使用服务帐户获得AI预测结果,并将云功能部署到Firebase项目。尝试获取预测结果时https://ml.googleapis.com/v1/projects / ...

node.js firebase google-cloud-functions access-token
1个回答
0
投票

现在正在工作。如here所述,我在模型级别将新的服务帐户设置为ML引擎模型用户。我还重置了以前的服务帐户,并且运行良好。谢谢@NibrassH和@DanielOcando。

© www.soinside.com 2019 - 2024. All rights reserved.