question

rfmaducd avatar image
rfmaducd asked

Unable to obtain access token using web server implementation

I've been following the instructions from https://developer.amazon.com/public/solutions/alexa/alexa-voice-service/docs/authorizing-your-alexa-enabled-product-from-a-website and using the companionservice app to try to get an access token with no success. I've modified the companionservice app so that it doesn't send a POST request for an initial access token, instead saves the authorization code and is then accessed using a GET request. Afterwards my plan was to make a POST request from my own app. I'm able to get the authorization code from the companionservice no problem but now I'm stuck trying to get an access token. Below is my request. POST /auth/o2/token HTTP/1.1 Host: api.amazon.com Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code={}&client_id={}&client_secret={}&redirect_uri=https://localhost:3000/authresponse I seem to connect just fine but get stuck with a malformed request. Any modifications I make to the header results in a specific error_description so it seems like the body parameters are the issue. nvalidRequestException: http://internal.amazon.com/coral/com.amazon.panda/ Content-Type: application/json Content-Length: 67 Vary: Accept-Encoding,User-Agent Cneonction: close {"error_description":"Malformed request","error":"invalid_request"}
alexa skills kitsubmission testing certification
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

rfmaducd avatar image
rfmaducd answered
Here's some more info HTTP/1.1 400 Bad Request Date: Tue, 29 Dec 2015 20:17:54 GMT Server: Server x-amzn-RequestId: 3e14fcb4-ae69-11e5-b1af-db5944928df3 X-Amz-Date: Tue, 29 Dec 2015 20:17:54 GMT x-amzn-ErrorType: OA2InvalidRequestException: http://internal.amazon.com/coral/com.amazon.panda/ Content-Type: application/json Content-Length: 67 Vary: Accept-Encoding,User-Agent Cneonction: close {"error_description":"Malformed request","error":"invalid_request"}
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

swasey@amazon avatar image
swasey@amazon answered
Could you describe what you're doing a little better? What I think you're doing is: -After logging in you store the authorization code in auth.authresponse, instead of calling and exchanging it for a refresh token. -You created a new GET path to fetch the authorization code from your AVS app code -Your AVS app has the client secret and client ID of the Node.js service -Your AVS app fetches the authorization code, and makes the request for a refresh token using the client secret and client id Is all that correct? A few things to point out: -Authorization codes have a lifespan of 5 minutes. After that they won't work. -It's unsafe to share the client secret in that fashion. Especially if the "AVS app" is mobile, because it exposes your secret. Did the unmodified service work? By that I mean, after you registered and the auth.authresponse function executed, were you able to get a refresh token using the authorization code? If that DID work, I'd imagine the problem is because you're waiting longer than 5 minutes, or your actual request on the AVS app side of things is incorrect. If that's the case, would you mind posting the code that you're using to make that request?
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

LasCondes avatar image
LasCondes answered
Hi swasey, I'm trying to do the same thing from a Lambda function and getting the same error. The private key and refresh_token would stay in the Lambda function. I am getting the following error: { "error_description": "Malformed request", "error": "invalid_request" } I am using the below code in a Lambda call: // var APIendpoint = ' https://api.amazon.com'; // var SANDBOXAPIendpoint = ' https://api.sandbox.amazon.com'; exports.handler = function(event, context) { var code = 'ANfjhsxxx; //event.code; event.data = ""; // From Amazon Seller Central var client_id = 'amzn1.application-oa2-client.f53xxx'; var client_secret = '7b7xxxx'; // var myPath = '/auth/o2/token?grant_type=authorization_code&code=' + encodeURI(code) + '&client_id='+client_id+'&client_secret='+client_secret; var myPath = '/auth/o2/token?grant_type=Authorization_code&code=' + encodeURI(code); var options = { hostname: ' api.sandbox.amazon.com', path: myPath, method: 'POST', agent: false, client_id: client_id, client_secret: client_secret, headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': event.data.length, 'client_id': client_id, 'client_secret': client_secret } }; console.log('myPath:', myPath); var https = require('https'); var req = https.request(options, function(res) { var body = ''; console.log('Status:', res.statusCode); console.log('Headers:', JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function(chunk) { body += chunk; }); res.on('end', function() { console.log('Successfully processed HTTPS response'); // If we know it's JSON, parse it if (res.headers['content-type'] === 'application/json') { body = JSON.parse(body); } context.succeed(body); }); }); req.on('error', context.fail); req.write(JSON.stringify(event.data)); req.end(); };
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

swasey@amazon avatar image
swasey@amazon answered
LasCondes, I'm not quite sure of your setup. Are you using Lambda as your redirect_url when setting up LWA for Websites? If that's the case, it looks like you might be missing a parameter in your commented our request. This line: > var myPath = '/auth/o2/token?grant_type=authorization_code&code=' + encodeURI(code) + '&client_id='+client_id+'&client_secret='+client_secret; Should also have a parameter for redirect_uri that includes the URL that you have listed in the LWA settings console. Basically, the URL of your Lambda function where this code is currently executing. If you'd like to see the code that does this you can look at authentication.js in our sample code for the companion service, under the "auth.authresponse" method.
1 comment
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

can you give link for companion service.

0 Likes 0 ·