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

智能家居技能开发:如何处理Alexa认证与AcceptGrant指令

智能家居Alexa技能账户链接与AcceptGrant指令详解

先纠正你的核心理解错误

Alexa会自动完成授权码兑换令牌的流程,不需要你在AcceptGrant指令里处理。完整流程是:

  1. 用户触发账户链接,跳转至你设置的Web Authorization URI完成授权,你的授权服务器返回授权码给Alexa。
  2. Alexa自动调用你设置的Access Token URI,用授权码兑换访问令牌(access token)和刷新令牌(refresh token),并自行存储这些令牌。
  3. 完成令牌兑换后,Alexa向你的技能发送AcceptGrant指令,通知你用户已完成授权,并传递用户身份关联的关键信息。

关于AcceptGrant指令的核心疑问

1. AcceptGrant的作用是什么?

它是Alexa向你发送的「授权完成确认通知」,核心目的是让你将Alexa侧的用户ID(grantee.token)与你的服务侧的用户ID做关联绑定,而非让你兑换令牌。

2. 收到AcceptGrant后该做什么?

  • 验证请求合法性:通过Alexa请求签名验证,确保请求来自官方。
  • 提取关键信息:
    • request.directive.grantee.token:Alexa生成的用户唯一标识(后续所有控制请求都会携带这个ID)。
    • request.context.System.user.accessToken:Alexa已经兑换好的、属于该用户的你的服务访问令牌。
  • 存储关联关系:将Alexa用户ID与你的服务用户ID(可从accessToken解析得到)绑定存储,比如存在DynamoDB、你的自有数据库中。
  • 返回成功响应:向Alexa返回AcceptGrant.Response,确认你已完成关联。

3. 令牌需要自己存储吗?

不需要。Alexa会帮你管理访问令牌和刷新令牌:

  • 后续所有控制请求(比如打开设备、查询状态)都会在context.System.user.accessToken中携带有效的访问令牌。
  • 当令牌过期时,Alexa会自动调用你的Access Token URI,用刷新令牌兑换新的访问令牌,全程无需你干预。

4. 如何识别请求对应的用户?

有两种可靠方式:

  • 方式一:解析请求中的accessToken(如果是JWT格式,直接解码即可获取你的服务用户ID)。
  • 方式二:用请求中的context.System.user.userId(即AcceptGrant中的grantee.token),通过你之前存储的关联关系,查询对应的你的服务用户ID。

Access Token URI的作用

这个URI是给Alexa调用的,承担两个核心功能:

  1. 接收Alexa发来的授权码,返回对应的访问令牌和刷新令牌(遵循OAuth2授权码模式规范)。
  2. 接收Alexa发来的刷新令牌,返回新的访问令牌(当旧令牌过期时)。
    你需要在你的授权服务器上实现这个接口,处理令牌兑换请求。

AcceptGrant指令的极简实现示例(伪代码)

function handleAcceptGrant(request) {
  // 1. 验证Alexa请求签名(必做,防止伪造请求)
  if (!verifyAlexaRequestSignature(request)) {
    return {
      event: {
        header: { namespace: 'Alexa', name: 'Error', payloadVersion: '3' },
        payload: { type: 'INVALID_REQUEST', message: '请求签名验证失败' }
      }
    };
  }

  // 2. 提取关键信息
  const alexaUserId = request.directive.grantee.token;
  const accessToken = request.context.System.user.accessToken;
  const yourServiceUserId = decodeUserIdFromJwt(accessToken); // 假设你的accessToken是JWT格式

  // 3. 存储用户关联关系(示例用数据库存储)
  db.saveUserMapping(alexaUserId, yourServiceUserId);

  // 4. 返回成功响应
  return {
    event: {
      header: { namespace: 'Alexa', name: 'AcceptGrant.Response', payloadVersion: '3' },
      payload: {}
    }
  };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:03:12