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.41k stars 2.12k forks source link

Can't access any resources related to auth outside route /sign-in #12754

Closed zohaibakber closed 8 months ago

zohaibakber commented 9 months ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

Authentication

Amplify Categories

auth

Environment information

``` # Put output below this line System: OS: Linux 6.6 Arch Linux CPU: (4) x64 Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz Memory: 1.34 GB / 7.65 GB Container: Yes Shell: 5.2.21 - /usr/bin/bash Binaries: Node: 21.4.0 - /sbin/node Yarn: 1.22.21 - /sbin/yarn npm: 10.2.5 - /sbin/npm pnpm: 8.12.1 - /sbin/pnpm bun: 1.0.16 - ~/.bun/bin/bun Browsers: Chromium: 120.0.6099.109 npmPackages: @aws-amplify/ui-react: ^6.0.7 => 6.0.7 @clerk/nextjs: ^4.29.1 => 4.29.1 @clerk/themes: ^1.7.9 => 1.7.9 @hookform/resolvers: ^3.3.2 => 3.3.2 @radix-ui/react-alert-dialog: ^1.0.5 => 1.0.5 @radix-ui/react-checkbox: ^1.0.4 => 1.0.4 @radix-ui/react-dialog: ^1.0.5 => 1.0.5 @radix-ui/react-dropdown-menu: ^2.0.6 => 2.0.6 @radix-ui/react-icons: ^1.3.0 => 1.3.0 @radix-ui/react-label: ^2.0.2 => 2.0.2 @radix-ui/react-radio-group: ^1.1.3 => 1.1.3 @radix-ui/react-scroll-area: ^1.0.5 => 1.0.5 @radix-ui/react-select: ^2.0.0 => 2.0.0 @radix-ui/react-separator: ^1.0.3 => 1.0.3 @radix-ui/react-slot: ^1.0.2 => 1.0.2 @radix-ui/react-tabs: ^1.0.4 => 1.0.4 @radix-ui/react-toast: ^1.1.5 => 1.1.5 @tailwindcss/aspect-ratio: ^0.4.2 => 0.4.2 @tanstack/react-query: ^5.14.6 => 5.14.6 @tanstack/react-query-devtools: ^5.14.7 => 5.14.7 @tanstack/react-table: ^8.11.2 => 8.11.2 @types/node: ^20.10.5 => 20.10.5 @types/react: ^18.2.45 => 18.2.45 @types/react-dom: ^18.2.18 => 18.2.18 autoprefixer: ^10.4.16 => 10.4.16 aws-amplify: ^6.0.9 => 6.0.9 axios: ^1.6.2 => 1.6.2 class-variance-authority: ^0.7.0 => 0.7.0 clsx: ^2.0.0 => 2.0.0 date-fns: ^3.0.6 => 3.0.6 eslint: ^8.56.0 => 8.56.0 eslint-config-next: 14.0.4 => 14.0.4 framer-motion: ^10.16.16 => 10.16.16 lucide-react: ^0.299.0 => 0.299.0 mini-svg-data-uri: ^1.4.4 => 1.4.4 next: 14.0.4 => 14.0.4 next-themes: ^0.2.1 => 0.2.1 postcss: ^8.4.32 => 8.4.32 react: ^18.2.0 => 18.2.0 react-day-picker: ^8.10.0 => 8.10.0 react-dom: ^18.2.0 => 18.2.0 react-hook-form: ^7.49.2 => 7.49.2 tailwind-merge: ^2.2.0 => 2.2.0 tailwindcss: ^3.4.0 => 3.4.0 tailwindcss-animate: ^1.0.7 => 1.0.7 typescript: ^5.3.3 => 5.3.3 zod: ^3.22.4 => 3.22.4 npmGlobalPackages: corepack: 0.23.0 node-gyp: 10.0.1 nopt: 7.2.0 npm: 10.2.5 pnpm: 8.12.1 semver: 7.5.4 yarn: 1.22.21 ```

Describe the bug

export async function handleSignIn({ username, password }: SignInInput) {
  try {
    const { isSignedIn, nextStep } = await signIn({
      username,
      password,
      options: { authFlowType: "USER_SRP_AUTH" },
    });

    if (isSignedIn) {
      console.log("signed in");
      const session = await fetchAuthSession();
      console.log("session", session);
    }
  } catch (error) {
    console.log("error signing in", error);
  }
}

Using above function to sign-in on route handler /sign-in in nextjs, After sign-in I can acess functions from "aws-amplify/auth" in the route but outside the route such as / or /dashboard I cant access any method like getCurrentUser(), I can see some data in local storage such as jwt token etc. stored.

Expected behavior

Resources should be available in all routes. Using WithAuthenticated from stored the user globally.

Reproduction steps

Install aws-amplify --> initialize Amplify.config() at layout -> handleSigin at route /sign-in

Code Snippet

"use client";

import { Button } from "@/components/ui/button";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { amplifyConfig } from "@/lib/amplify.config";
import { Input } from "@/components/ui/input";
import { zodResolver } from "@hookform/resolvers/zod";
import { Amplify } from "aws-amplify";
import { useForm } from "react-hook-form";
import * as z from "zod";
// import { handleSignIn } from "@/app/actions/sign-in";
import { signIn, type SignInInput, fetchAuthSession } from "aws-amplify/auth";

Amplify.configure(amplifyConfig);
export async function handleSignIn({ username, password }: SignInInput) {
  try {
    const { isSignedIn, nextStep } = await signIn({
      username,
      password,
      options: { authFlowType: "USER_SRP_AUTH" },
    });

    if (isSignedIn) {
      console.log("signed in");
      const session = await fetchAuthSession();
      console.log("session", session);
    }
  } catch (error) {
    console.log("error signing in", error);
  }
}

const formSchema = z.object({
  email: z.string().min(1).email(),
  password: z.string().min(8),
});
export default function Page() {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      email: "",
      password: "",
    },
  });

  const handleSumbit = async (data: z.infer<typeof formSchema>) => {
    console.log(data);
    const res = await handleSignIn({
      username: data.email,
      password: data.password,
    });
    console.log(res);
  };
  return (
    <div className="flex items-center justify-center h-screen">
      <Form {...form}>
        <form className="space-y-2" onSubmit={form.handleSubmit(handleSumbit)}>
          <FormField
            control={form.control}
            name="email"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Email</FormLabel>
                <FormControl>
                  <Input placeholder="madmax@lol.com" {...field} />
                </FormControl>
                <FormDescription>Email</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="password"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Password</FormLabel>
                <FormControl>
                  <Input {...field} type="password" />
                </FormControl>
                <FormDescription>
                  Password must be atleast 8 characters
                </FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />
          <Button type="submit" className="w-full">
            Submit
          </Button>
        </form>
      </Form>
    </div>
  );
}

Log output

``` ../node_modules/.pnpm/@aws-amplify+auth@6.0.9_@aws-amplify+core@6.0.9/node_modules/@aws-amplify/auth/dist/esm/providers/cognito/utils/types.mjs (16:14) @ assertAuthTokens ⨯ UserUnAuthenticatedException: User needs to be authenticated to call this API. at async DashboardPage (dashboard/page.tsx:16:18) ```

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

israx commented 8 months ago

Hello @zohaibakber . You are able to call APIs under the /sign-in route because that page currently has the Amplify configuration, which is accessed by the Amplify APIs. However Next JS doesn't behave as single page application app, where everything is loaded at once on the browser. If you want to call APIs on the client side you would need to configure Amplify in a shared route.

If you want to integrate Amplify in the server, we have a guide that you can follow: https://docs.amplify.aws/nextjs/build-a-backend/server-side-rendering/

cwomack commented 8 months ago

@zohaibakber, can you let us know if the comment above from @israx helped clarify things and unblock you? Thanks!

zohaibakber commented 8 months ago

Yea figured it out, thanks for the help