You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node环境下Actions-on-Google结合Auth0账号关联如何获取认证提供商

Shaun,我明白你赶项目的焦虑——这个问题确实有点坑,因为Actions on Google V2的SignIn意图返回的对象里确实不会直接携带用户选择的认证提供商信息,但咱们可以从Auth0的配置和后续API调用入手解决,步骤其实很清晰:

核心思路

Actions on Google的SignIn只负责完成认证流程并返回Token,而用户的登录提供商信息需要从Auth0那边获取——我们可以通过Auth0的规则把提供商信息注入到Token或用户信息接口中,再在你的Node.js应用里提取出来。

步骤1:在Auth0中添加规则,注入提供商信息

登录Auth0控制台,进入Rules页面,点击「Create Rule」新建一个规则,选择「Empty Rule」模板,替换成以下代码:

function addProviderToUserInfo(user, context, callback) {
  // 把提供商信息添加到userinfo响应和ID Token的自定义声明中
  context.idToken['https://your-custom-namespace.com/provider'] = user.provider;
  context.accessToken['https://your-custom-namespace.com/provider'] = user.provider;
  // 同时确保provider字段出现在userinfo的返回结果里
  context.userInfo.provider = user.provider;
  
  callback(null, user, context);
}

注意:https://your-custom-namespace.com/provider是自定义声明的命名空间,必须是合法的URL格式(可以用你自己的域名或者项目相关的URL),目的是避免和OpenID标准声明冲突。

步骤2:在你的Node.js应用中获取提供商信息

你已经拿到了Access Token,接下来可以通过两种方式获取带提供商信息的用户数据:

方式一:调用Auth0的UserInfo接口(推荐)

用你喜欢的HTTP库(比如axios)调用Auth0的/userinfo端点,这个接口会直接返回包含provider字段的用户档案:

const axios = require('axios');

async function handleSignInConfirmation(conv, params, signin) {
  if (signin.status === 'OK') {
    const accessToken = conv.user.access.token;
    const auth0Domain = '你的Auth0域名(比如xxx.auth0.com)';
    
    try {
      const response = await axios.get(`https://${auth0Domain}/userinfo`, {
        headers: {
          Authorization: `Bearer ${accessToken}`
        }
      });
      
      // 获取关键信息
      const userProvider = response.data.provider; // 比如返回'google-oauth2'、'facebook'、'twitter'
      const userName = response.data.name;
      const userEmail = response.data.email;
      
      // 接下来就可以根据provider做对应的逻辑处理了
      conv.ask(`欢迎回来${userName}!你使用${userProvider}完成了登录~`);
    } catch (err) {
      console.error('获取用户信息失败:', err);
      conv.ask('抱歉,暂时无法获取你的账户信息,请稍后重试。');
    }
  } else {
    conv.ask('登录未完成,请重试哦。');
  }
}

方式二:解码ID Token获取提供商信息

如果你已经拿到了ID Token(因为你请求了OPENID权限,所以conv.user.idToken应该能拿到),可以用jsonwebtoken库解码并提取自定义声明:

const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa'); // 用来获取Auth0的公钥,确保Token验证安全

async function getProviderFromIDToken(idToken, auth0Domain, clientId) {
  // 初始化JWKS客户端获取公钥
  const client = jwksClient({
    jwksUri: `https://${auth0Domain}/.well-known/jwks.json`
  });

  function getKey(header, callback) {
    client.getSigningKey(header.kid, function(err, key) {
      const signingKey = key.getPublicKey();
      callback(null, signingKey);
    });
  }

  // 验证并解码Token(一定要验证,防止伪造)
  return new Promise((resolve, reject) => {
    jwt.verify(idToken, getKey, {
      audience: clientId,
      issuer: `https://${auth0Domain}/`
    }, (err, decoded) => {
      if (err) reject(err);
      // 提取自定义声明里的提供商信息
      const provider = decoded['https://your-custom-namespace.com/provider'];
      resolve(provider);
    });
  });
}

// 在意图处理器中调用
async function handleSignInConfirmation(conv, params, signin) {
  if (signin.status === 'OK') {
    const idToken = conv.user.idToken;
    const auth0Domain = '你的Auth0域名';
    const clientId = '你的Auth0客户端ID';
    
    try {
      const userProvider = await getProviderFromIDToken(idToken, auth0Domain, clientId);
      // 后续逻辑...
    } catch (err) {
      console.error('解码Token失败:', err);
      // 错误处理...
    }
  }
}

额外检查

确保你的Auth0应用配置正确:

  • 在Connections里已经启用了Google、Facebook、Twitter
  • 在Applications -> 你的应用 -> Settings中,Allowed Callback URLs已经添加了Actions on Google的回调地址:https://oauth-redirect.googleusercontent.com/r/你的项目ID

这样就能顺利拿到用户选择的认证提供商,进而正确处理用户档案信息了,祝项目顺利上线!

内容的提问来源于stack exchange,提问作者Shaun Heveron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:25:04