邮递员请求Amazon Alexa智能家居技能LWA的客户端身份验证失败

时间:2018-11-21 10:24:58

标签: amazon-web-services oauth postman alexa

出于客户认证的目的,我指的是Amazon documentation。目前,我正在使用LWA。

我遵循的步骤:

  1. 我在“构建”>“权限”页面中从Alexa开发人员控制台启用了“发送Alexa事件”权限。

  2. 我从cloudwatch日志中的请求中提取了授权代码,该请求是我使用Alexa配套应用登录时发送的。

示例:-

    {
     "directive": {
         "header": {
             "messageId": "Example",
             "name": "AcceptGrant",
             "namespace": "Alexa.Authorization",
             "payloadVersion": "3"
         },
         "payload": {
            "grant": {
                "code": "Example2",
                "type": "OAuth2.AuthorizationCode"
            },
            "grantee": {
                "token": "Example3",
                "type": "BearerToken"
            }
         }
      }
    }
  1. Alexa开发人员控制台上正在构建的权限页面为我提供了client-Id和client-secret,它们用于向https://api.amazon.com/auth/o2/token发出发布请求。

示例:-

 POST /auth/o2/token HTTP/l.l
 Host: api.amazon.com
 Content-Type: application/x-www-form-urlencoded;charset=UTF-8 
 grant_type=authorization_code&code=&client_id=&client_secret=

我在上面的示例中传递了代码,client_id和client_secret,并向该URL https://api.amazon.com/auth/o2/token发出了发布请求

  1. 我尝试使用x-www-form-urlencoded; charset = UTF-8以及JSON作为Content-Type。

我按照上述文档中的步骤进行操作,但我陷入了错误(401未经授权)的问题:

{
    "error_description": "The request has an invalid grant parameter : code",
    "error": "invalid_grant"
}

我尝试使用Python代码和Postman来实现它。最终出现上述相同的错误情况。

1 个答案:

答案 0 :(得分:0)

这是示例代码,可帮助您和其他希望将事件发送到alexa网关的人。

const AWS = require('aws-sdk');
AWS.config.update({region: 'eu-west-1'});

// Create the DynamoDB service object
const ddb = new AWS.DynamoDB({ apiVersion: 'latest' });
const doc = new AWS.DynamoDB.DocumentClient({
            convertEmptyValues: true,
            service: ddb
        });        

// Using 'request' for http POST and GET request.
// https://www.npmjs.com/package/requests
// npm install --save requests 
const r = require('request');

//Handle Authorization. Call this method from your lambda handler whenever you get Alexa.Authorization message. You will get this message only when you select permission to 
//send events in your Smart Home Skill.
//Access to Event gateway allows you to enable Proactive Device Discovery and 
//Proactive State Reporting in your skill
//More information on Alexa.Authorization can be found on https://developer.amazon.com/docs/device-apis/alexa-authorization.html
function handleAuthorization(request, context, user) {  

    //Even when you are using your own authentication, the url below will still
    //point to amazon OAuth token url. The token you obtain here has to be stored
    //separately for this user. Whenever sending an event to alexa event gateway you will
    //require this token.
    //URL below is for EU server. Look at following documentation link to identify correct url
    //for your system.
    //https://developer.amazon.com/docs/smarthome/send-events-to-the-alexa-event-gateway.html
    var url = "https://api.amazon.com/auth/o2/token";
    var body = {
        grant_type : 'authorization_code',
        code : request.directive.payload.grant.code,
        client_id : 'your client id from permissions page on developer portal where you enable alexa events. This is id different than one you specify in account linking settings',
        client_secret : 'client secret from permissions page'
    }

    //https://developer.amazon.com/docs/smarthome/authenticate-a-customer-permissions.html
    r.post({
      url:     url,
      form :  body
    }, function(error, response, b){    
        if (error) { return console.log(error); }
        var body = JSON.parse(b);
        var params = {
          TableName: 'Devices',
          Item: {
            'id' : user,
            'auth_token' : body.access_token,
            'refresh_token' : body.refresh_token
          }
        }
        log("DEBUG:", "Authorization Body", JSON.stringify(body));
        log("DEBUG:", "Authorization Response", JSON.stringify(response));
        log("DEBUG:", "Database Params", JSON.stringify(params));

        // Call DynamoDB to add the item to the table
        var putObjectPromise = doc.put(params).promise();
        //Store auth_token and refresh_token in database. We will need these
        //while sending events to event gateway.
        //Send a success response.
        putObjectPromise.then(function(data) {
            var response = {
              event: {
                header: {
                  messageId: request.directive.header.messageId,
                  namespace: "Alexa.Authorization",
                  name: "AcceptGrant.Response",
                  payloadVersion: "3"
                },
                "payload": {
                }
              }
            };

            context.succeed(response);
        }).catch(function(err) {
            //TODO - Add a Authorization error response JSON here.      
            console.log(err);
        });                         
    });                   
}