question

Optimus avatar image
Optimus asked

Login with Amazon says user has not consented, but they have - Alexa SMAPI

I'm trying to retrieve a list of skills on my Alexa developer account using the Skill Management API (SMAPI).

I have the following HTML/javascript:

<BODY>
<a href id="LoginWithAmazon">
    <img border="0" alt="Login with Amazon" src="https://images-na.ssl-images-amazon.com/images/G/01/lwa/btnLWA_gry_312x64.png" width="156" height="32"/>
</a><div id="amazon-root"></div>
<script type="text/javascript">
    var client_id ="<client id>";
    window.onAmazonLoginReady =function(){
        amazon.Login.setClientId(client_id);
    };
    (function(d){
        var a = d.createElement('script');
        a.type ='text/javascript';
        a.async=true; a.id ='amazon-login-sdk';
        a.src ='https://api-cdn.amazon.com/sdk/login1.js';
        d.getElementById('amazon-root').appendChild(a);
    })(document);
    document.getElementById('LoginWithAmazon').onclick =function(){
        options ={
            scope :'profile postal_code alexa::ask:skills:readwrite alexa::ask:models:readwrite alexa::ask:skills:test',
            interactive:'always',
            response_type:'code'
        };
        amazon.Login.authorize(options,'<login page url>');
    returnfalse;};
</script>
</BODY>

Which then calls the login page to get the appropriate access token:

$grant_type ='authorization_code';
$client_id = $GLOBALS['client_id']; //your client id
$client_secret = $GLOBALS['client_secret']; //your client secret

$data = array("grant_type"=>"authorization_code","code"=> $code,"client_id"=> $client_id,"client_secret"=> $client_secret);
$postvars ='';
foreach($data as $key=>$value){
    $postvars .= $key ."=". $value ."&";
}
$ch = curl_init('https://api.amazon.com/auth/o2/token');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,"POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded;charset=UTF-8'));
$result = curl_exec($ch);
curl_close($ch);
$result_arr = json_decode($result,true);
if(isset($result_arr['error'])==true){ //there was an error obtaining the auth token 
    var_dump($result);
    die('Error: There was an error authenticating with Amazon. Can you please start over again? Click <a href="index.php">here</a> to start again.');
}
return $result_arr;

I can use the access_token in the $result_arr to get profile information, but when I use it to get a list of skills:

// exchange the access token for list of skills
$c = curl_init('https://api.amazonalexa.com/v0/skills/');
curl_setopt($c, CURLOPT_HTTPHEADER, array('Authorization: '. $access_token));
curl_setopt($c, CURLOPT_RETURNTRANSFER,true);
curl_setopt($c, CURLOPT_VERBOSE,1);
curl_setopt($c, CURLOPT_POST,1);

$r = curl_exec($c);
curl_close($c);
var_dump($r);

I receive User has not consented to this operation

I must be missing something basic here. I was under the impression that the scope in the initial request: profile postal_code alexa::ask:skills:readwrite alexa::ask:models:readwrite alexa::ask:skills:test would be sufficient to give access. I've confirmed that the Amazon account shows the app having access to the above permissions.

alexa skills kitlogin with amazonsmapi
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.

Jenn@amazon avatar image
Jenn@amazon answered

Look like you're missing one of the scopes:

alexa::ask:skills:read

List the vendor IDs associated with the Amazon developer account Read skill details (excluding interaction models)). Get skill status. Get list of skills.

https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/ask-cli-intro#smapi-intro

10 |5000

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

isabin avatar image
isabin answered

I am having the same issue and I believe I am setting the scope properly:

alexa::ask:skills:read alexa::ask:models:read profile

url-encoded form:

alexa%3A%3Aask%3Askills%3Aread%20alexa%3A%3Aask%3Amodels%3Aread%20profile

Here is the URL:

https://www.amazon.com/ap/oa?client_id=XXX&scope=alexa%3A%3Aask%3Askills%3Aread%20alexa%3A%3Aask%3Amodels%3Aread%20profile&response_type=code&state=YYY&redirect_uri=ZZZ

2 comments
10 |5000

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

This may be just an error copying and pasting the URL here, but your scope parameter doesn't look right. There's a greater than symbol instead of an ampersand between client_id parameter and the scope parameter, and you have the scope parameter named "ope" instead of "scope".

1 Like 1 ·

Thanks for your response. Very good observation. Even though I pasted the correct URL (i.e. one that doesn't have the greater symbol), when I look at it in the message I see the greater character. I tried editing the message a couple of times w/o being able to remove the character. So, the actual URL doesn't have this issue.

0 Likes 0 ·
brian.dinga avatar image
brian.dinga answered

I've been at this issue on/off for about a week now. I thought I was misunderstanding the documentation (which I was at first) but now I've gotten this far I'm puzzled as to what the issue is.

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 someone from Amazon's team please confirm whether this is a defect? We are experiencing the same behavior and looking forward to a resolution (or more clarity in the documentation). For more information see the message I posted a few days ago.

0 Likes 0 ·
GadgetChannel avatar image
GadgetChannel answered

I had a problem when I was writing an application using the AVS and wanted it to be able to access both AVS and profile information. It seemed that the profile scope and the alexa:all scope used by AVS wouldn't work properly together and I needed to authenticate twice, once with each scope. It may be that this is the same with the alexa::ask:... scopes. In that case, try removing the profile scope and see if this allows access to the skills.

3 comments
10 |5000

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

Brilliant, that fixed it. Thanks!

0 Likes 0 ·

Yea this fixed it for me too!

I thought this was something I tried. Thanks @GadgetChannel!

0 Likes 0 ·

Fixed like a charm!

0 Likes 0 ·
Jonathan Horniblow avatar image
Jonathan Horniblow answered

Can anyone please take a look and see where the problem is here?


ask util generate-lwa-tokens --client-id amzn1.application-oa2-client.02d9XXXXXXXXXXXXX746dc554 --client-confirmation 382aXXXXXXXXf4765 --no-browser --scopes alexa::ask:skills:readwrite alexa::ask:models:readwrite alexa::ask:skills:test


I can list skills, I can read and update the manifest, but I cannot read or update the interaction model


await smapiClient.callSetInteractionModelV1(skillId, stage, locale, interactionModel)

or


await smapiClient.callGetInteractionModelV1(skillId, 'development', 'en-GB')


Error [ServiceError]: The auth token is invalid/expired or doesn&#39;t have access to the resource.
    at SkillManagementServiceClient.<anonymous> (/home/ubuntu/scripts/alexa/individual-TN-V6/smapi-skill-creator/node_modules/ask-sdk-model-runtime/dist/index.js:330:31)
    at step (/home/ubuntu/scripts/alexa/individual-TN-V6/smapi-skill-creator/node_modules/ask-sdk-model-runtime/dist/index.js:54:23)
    at Object.next (/home/ubuntu/scripts/alexa/individual-TN-V6/smapi-skill-creator/node_modules/ask-sdk-model-runtime/dist/index.js:35:53)
    at fulfilled (/home/ubuntu/scripts/alexa/individual-TN-V6/smapi-skill-creator/node_modules/ask-sdk-model-runtime/dist/index.js:26:58)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  statusCode: 401,
  headers: [
    { key: 'content-type', value: 'application/json' },
    { key: 'content-length', value: '55' },
    { key: 'connection', value: 'close' },
    { key: 'server', value: 'Server' },
    { key: 'date', value: 'Mon, 10 Aug 2020 19:43:49 GMT' },
    { key: 'x-amz-rid', value: '5RXXXXX },
    {
      key: 'x-amzn-requestid',
      value: 'd5e63873-7xxxxxxxxxxx29-9c7cb9f0cfa7'
    },
    { key: 'x-amz-date', value: 'Mon, 10 Aug 2020 19:43:49 GMT' },
    {
      key: 'www-authenticate',
      value: 'Bearer realm="Login with Amazon"'
    },
    {
      key: 'vary',
      value: 'Content-Type,Accept-Encoding,X-Amzn-CDN-Cache,X-Amzn-AX-Treatment,User-Agent'
    },
    { key: 'x-cache', value: 'Error from cloudfront' },
    {
      key: 'via',
      value: '1.1 c58525b19xxxxxxxxxxx.cloudfront.net (CloudFront)'
    },
    { key: 'x-amz-cf-pop', value: 'LHR52-C1' },
    {
      key: 'x-amz-cf-id',
      value: '09vfZvXY87b9Fae5zgXxxxxxxxxxxxxxxxxxxx9aObfGW0JqH2QTg=='
    }
  ],
  response: { message: 'User has not consented to this operation.' }
}
2 comments
10 |5000

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

Hi @Jonathan and thanks for your message.

I have reached out to our internal teams and will update you once I hear back from them.

Regards,
Barry

0 Likes 0 ·

Hello @Jonathan and thank you for your patience.

It turns out that, when requesting multiple scopes, they should be between double quotes ("). Your ask util command should look like this:

ask util generate-lwa-tokens --client-id amzn1.application-oa2-client.02d9XXXXXXXXXXXXX746dc554 --client-confirmation 382aXXXXXXXXf4765 --no-browser --scopes "alexa::ask:skills:readwrite alexa::ask:models:readwrite alexa::ask:skills:test"

I tested with the above syntax and was able to retrieve the interaction model for one of my skills. Without the quotes, I was getting the same error.

I am in touch with the documentation team to add this bit of information to the appropriate ASK CLI reference page.

Regards,
Barry

0 Likes 0 ·