aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

Amplify Rest API Next js, Not signing the request with aws credential #13378

Closed AtharvArolkar closed 1 month ago

AtharvArolkar commented 4 months ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

REST API

Amplify Version

v6

Amplify Categories

api

Backend

CDK

Environment information

``` # Put output below this line ```

Describe the bug

Im trying to make a REST API request, when the request is called, I get the following error

IncompleteSignatureException: Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header. Authorization=eyJraWQiOiJRQU5N............

I checked the network tab, the request headers don't contain the AWS signed request headers. Following in my code:

import { fetchAuthSession } from "aws-amplify/auth/server";
import { post } from "aws-amplify/api";
import { cookies } from "next/headers";
import { apiRoutes } from "@/routes";
import { RestApiResponse } from "@aws-amplify/api-rest/dist/esm/types";
import { runWithAmplifyServerContext } from "@/utils/amplifyServerUtils";

const callPostApi = async ({
  url,
  payload,
}: CallPostApiType): Promise<RestApiResponse> => {
  try {
    const data = await runWithAmplifyServerContext({
      nextServerContext: { cookies },
      operation: async (contextSpec) => {
        const authToken = await fetchAuthSession(contextSpec);
        return post({
          apiName: process.env.NEXT_PUBLIC_AMPLIFY_API_ENDPOINT_NAME as string,
          path: `${url}`,
          options: {
            headers: {
              "x-api-key": atob(
                process.env.NEXT_PUBLIC_AMPLIFY_API_API_KEY as string
              ),
              Authorization: authToken.tokens?.idToken?.toString()!,
            },
            body: payload,
          },
        });
      },
    });
    return data.response;
  } catch (error) {
    throw error;
  }

This is my configuration file:

import { ResourcesConfig } from "aws-amplify";
export const amplifyConfig: ResourcesConfig = {
  Auth: {
    Cognito: {
      userPoolId: process.env.NEXT_PUBLIC_AMPLIFY_AUTH_USER_POOL_ID!,
      userPoolClientId:
        process.env.NEXT_PUBLIC_AMPLIFY_AUTH_USER_POOL_WEB_CLIENT_ID!,
      identityPoolId: process.env.NEXT_PUBLIC_AMPLIFY_AUTH_IDENTITY_POOL_ID!,
      loginWith: {
        oauth: {
          providers: ["Google"],
          domain: process.env.NEXT_PUBLIC_AMPLIFY_OAUTH_DOMAIN!,
          scopes: [
            "openid",
            "email",
            "profile",
            "aws.cognito.signin.user.admin",
          ],
          redirectSignIn: [
            process.env.NEXT_PUBLIC_AMPLIFY_OAUTH_REDIRECT_SIGN_IN!,
          ],
          redirectSignOut: [
            process.env.NEXT_PUBLIC_AMPLIFY_OAUTH_REDIRECT_SIGN_OUT!,
          ],
          responseType: "code",
        },
      },
    },
  },
  API: {
    REST: {
      "apiName": {
        endpoint: process.env.NEXT_PUBLIC_AMPLIFY_API_ENDPOINT!,
        region: process.env.NEXT_PUBLIC_AMPLIFY_AUTH_REGION!,
      },
    },
  },
};

But if i make the api call with axios object and manually sign the request, the api call is successfull

import { fetchAuthSession } from "aws-amplify/auth";

const authToken = await fetchAuthSession();

    const interceptor = aws4Interceptor({
      options: {
        region: "eu-west-1",
        service: "execute-api",
      },
      credentials: {
        accessKeyId: authToken.credentials?.accessKeyId!,
        secretAccessKey: authToken.credentials?.secretAccessKey!,
        sessionToken: authToken.credentials?.sessionToken,
      },
    });
    const client = axios.create({
      headers: {
        "X-Api-Key": atob(
          process.env.NEXT_PUBLIC_AMPLIFY_API_API_KEY as string
        ),
      },
    });
    client.interceptors.request.use(interceptor);

    const result= await client.post(
      "api url"
    );

Note : fetchAuthSession is configured using the same configuration file, mentioned above

Expected behavior

As per what is mentioned in the docs, AWS Docs the request should be automatically signed with the aws credentials, but it doesn't seem to be happening over here.

Reproduction steps

  1. Install aws-amplify 6.3.0
  2. Configure amplify in both client and server side
  3. perform IAM login
  4. Perform a Post Rest API call

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

cwomack commented 4 months ago

Hello, @AtharvArolkar and thank you for opening this issue. Going to tag a related issue, #13310 here and mark this is a bug that's a version parity difference from v5 and v6 behavior.

Would you mind also sharing some context around the use case and why you're looking to pass the x-api-key and IAM Auth as well? We'd appreciate some additional details from you or anyone else on this issue. Thanks!

AtharvArolkar commented 4 months ago

Hi @cwomack, We are using both the x-api-key and the IAM authorization to authorize the Rest API Gateway request, as our Gateway is configured such that, method request requires the API Key. If API Key is not provided, then the Gateway throws a 403 error response.

ashika112 commented 4 months ago

@AtharvArolkar, thank you for the use case. we are currently working on fixing this without breaking customers. I will update the ticket once we have a PR out for the issue.

AtharvArolkar commented 4 months ago

Hi @ashika112 , @cwomack , any updates on this issue?

ashika112 commented 4 months ago

Opened up a draft PR i will add in tests and get this to review soon.

AtharvArolkar commented 3 months ago

Hi @ashika112 , any updates on the PR?

ashika112 commented 3 months ago

Hi updated the PR and is in review now.

AtharvArolkar commented 2 months ago

Hi @ashika112 @cwomack , Any updates on this?

ashika112 commented 1 month ago

HI @AtharvArolkar , the fix is now available in aws-amplify@latest [version 6.5.3]. Closing this issue, please let us know if you have any further concerns.

AtharvArolkar commented 1 month ago

Thank You!! @ashika112 . Will try it out. :)