Войдите в систему с помощью Amazon для Alexa Skills (LWA)

У кого-нибудь есть комплексное решение для LWA и AWS Lambda? О том, когда я думаю, что понимаю протокол запроса/ответа, я больше запутываюсь, когда пытаюсь заставить его работать.


person NHLIVES    schedule 05.05.2018    source источник
comment
Я использую Logon with Amazon для аутентификации своих пользователей. Кажется, он работает нормально, но мне нужна информация профиля, которая, по-видимому, авторизована во время входа в систему клиента. Проблема в том, что я не вижу, как получить доступ к информации из функции Lambda, связанной с умным домом.   -  person NHLIVES    schedule 06.05.2018
comment
Какой-то код или ссылка всегда помогали мне помогать другим.   -  person Nikhil Wagh    schedule 08.06.2018


Ответы (2)


URL-адрес: https://api.amazon.com/user/profile. Вы должны передать токен OAuth 2.0 одним из трех способов: как параметр в URL-адресе, как токен носителя в заголовке или как XML. Вот ссылка: https://login.amazon.com/website. Токен очень длинный и для Amazon должен быть закодирован. Это может сделать его слишком длинным для URL-адреса. Я использовал подход заголовка.

    public static WebClient client = new WebClient();
    public static JObject GetAmznProfile(string token)
    {
        string amznProfileHost = "https://api.amazon.com/user/profile";
        try
        {
            client.Headers.Remove("user-agent");
            client.Headers.Remove("Authorization");
            client.Headers.Add("Authorization: bearer " + token);
        }
        catch { Logger(Constants.SEVERE, "Exception caught trying to modify http headers in \"GetAmznProfile\""); }
        finally { }

        string body = GetUrl(amznProfileHost);
        if (body != null)
        {
            JObject json = JObject.Parse(body);
            return json;
        }
        else
        {
            string error = @"{'user_id':'error','name':'error','email':'error'}";
            JObject json = JObject.Parse(error);
            return json;
        }
    }

    public static string GetUrl(string url)
    {
        Logger(Constants.DEBUG, "In 'GetUrl' the URL is " + url);
        try
        {
            Stream data = client.OpenRead(url);
            StreamReader reader = new StreamReader(data);
            string body = reader.ReadToEnd();
            data.Close();
            reader.Close();

            return body;
        }
        catch (WebException e) { Logger(Constants.INFO, e.ToString() + " exception caught"); return null; }
    }
person NHLIVES    schedule 11.06.2018

В поисках решения этого вопроса я наткнулся на этот вопрос. Ответ NHLIVES для меня не проблема, так как я использую node.js. Следующий код является неполным и изменен из примера Amazon, но не должен содержать ошибок. Его, безусловно, можно улучшить. Но это сработало для меня, и я надеюсь, что это будет полезно для следующего человека в будущем.

Еще одна вещь: модуль «запрос» недоступен в Lambda, поэтому вы должны его предоставить. Просто создайте zip-файл с вашим index.js на верхнем уровне, каталогом node_modules, содержащим каталоги «request» и «safe-buffer» (скопированные из вашей локальной установки узла), и загрузите zip-файл в Amazon Lambda (в AWS Lambda: «Тип ввода кода»: «Загрузить файл .zip»).

var AWS = require('aws-sdk');
var requestlib = require('request');

exports.handler = function (request, context) {

    var whoami = async function (request) {
        var amznProfileURL = 'https://api.amazon.com/user/profile?access_token=';

        if (request.directive.header.namespace === 'Alexa.Discovery' && request.directive.header.name === 'Discover') {
            amznProfileURL += request.directive.payload.scope.token;
        } else {
            amznProfileURL += request.directive.endpoint.scope.token;
        }

        await new Promise(function(resolve, reject) {
            log("LWArequest: ", "amznProfileURL ", amznProfileURL);
            requestlib(amznProfileURL, function(error, response, body) {
                if (response.statusCode == 200) {
                    var profile = JSON.parse(body);
                    log("LWArequest: ", "user_id ", body);
                    resolve();
                } else {
                    log("LWArequest: ", "error ", "can't connect to Amazon Profile Service");
                    reject();
                }
            });
        }
        );
    }

    whoami(request);
    if (request.directive.header.namespace === 'Alexa.Discovery' && request.directive.header.name === 'Discover') {
        log("DEBUG:", "Discover request",  JSON.stringify(request));
        handleDiscovery(request, context, "");
    }

    function log(message, message1, message2) {
        console.log(message + message1 + message2);
    }

}

Вы должны увидеть что-то подобное в файле журнала CloudWatch:

2018-07-17T23:06:28.108Z    08d795d3-8a16-11e8-b912-0f46b6510aa8    
  LWArequest: amznProfileURL https://api.amazon.com/user/profile?access_token=Atza|IwEBIP5ozi...

2018-07-17T23:06:28.409Z    08d795d3-8a16-11e8-b912-0f46b6510aa8    
  LWArequest: user_id
  {
    "user_id": "amzn1.account.A..........................A"
  }

Надеюсь, поможет.

person user1261470    schedule 17.07.2018