5

I have this /app/auth/login/route.ts

import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'

export async function POST(request: Request) {
  const requestUrl = new URL(request.url)
  const formData = await request.formData()
  const email = String(formData.get('email'))
  const password = String(formData.get('password'))
  const cookieStore = cookies()
  const supabase = createRouteHandlerClient({ cookies: () => cookieStore })

  await supabase.auth.signInWithPassword({
    email,
    password,
  })

  return NextResponse.redirect(requestUrl.origin, {
    status: 301,
  })
}

And the page which is on /app/login/page.tsx

import Link from "next/link";

export default function LoginPage() {
  return (
    <>
      <form action="/auth/login" method="post">
      <label htmlFor="email">Email</label>
      <input name="email" />
      <label htmlFor="password">Password</label>
      <input type="password" name="password" />
      <button>Sign In</button>
    </form>

    <Link href="/reset-password">Reset Password</Link>
    </>
  )
}

Those were the codes that I got from the documentation. I am, however, unable to implement where it displays that they have successfully logged in and the error handling.

I followed answers below, however, I am receiving this error:

POST http://localhost:3000/auth/login net::ERR_ABORTED 405 (Method Not> Allowed)

route.ts

import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { NextApiRequest, NextApiResponse } from 'next'; // Correct import for NextApiRequest and NextApiResponse
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server'; // Correct import for NextResponse

export async function handler(
  req: NextApiRequest, // Correct the parameter list
  res: NextApiResponse // Correct the parameter list
) {
  const jsonBody = await req.body.json(); // Change 'request' to 'req'
  const email = jsonBody.email;
  const password = jsonBody.password;
  const cookieStore = cookies();
  const supabase = createRouteHandlerClient({ cookies: () => cookieStore });

  try {
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      return res.status(401).json({ message: 'Login failed. Please check your credentials.' });
    }
    return res.status(200).json({ message: 'Login successful' });
  } catch (error) {
    console.error('An error occurred:', error);
    return res.status(500).json({ message: 'An unexpected error occurred' });
  }
}

api/login/page.tsx

'use client'

import { useRouter } from 'next/navigation';
import { useState } from 'react';

export default function LoginPage() {
  const router = useRouter();
  const [error, setError] = useState<string>('');
  const [email, setEmail] = useState<string>('');
  const [password, setPassword] = useState<string>('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');
  
    try {
      const response = await fetch('/auth/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email, password }),
      });
  
      if (response.status === 200) {
        router.push('/');
      } else {
        if (response.headers.get('content-type')?.includes('application/json')) {
          // Check if the response contains JSON data.
          const result = await response.json();
          setError(result.message);
        } else {
          // Handle non-JSON responses (e.g., empty responses).
          setError('An unexpected error occurred.');
        }
      }
    } catch (error) {
      console.log(error, "error on the login page.tsx")
      console.error('An error occurred:', error);
      setError('An unexpected error occurred.');
    }
  }; 

  return (
    <>
      <form onSubmit={handleSubmit}>
        <label htmlFor="email">Email</label>
        <input
          type="email"
          name="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <label htmlFor="password">Password</label>
        <input
          type="password"
          name="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
        <button type="submit">Sign In</button>
      </form>

      {error && <p>{error}</p>}
    </>
  );
}
0

1 Answer 1

0

I think you should send a POST json request, handling it with javascript:

import { useRouter } from 'next/router';
import { useState } from 'react';

export default function LoginPage() {
  const router = useRouter();
  const [error, setError] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError('');

    try {
      const response = await fetch('/auth/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email, password }),
      });

      if (response.status === 200) {
        router.push('/some-page-after-login')
      } else {
        const result = await response.json();
        setError(result.message);
      }
    } catch (error) {
      console.error('An error occurred:', error);
      setError('An unexpected error occurred.');
    }
  };

  return (
    <>
      <form onSubmit={handleSubmit}>
        <label htmlFor="email">Email</label>
        <input
          type="email"
          name="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <label htmlFor="password">Password</label>
        <input
          type="password"
          name="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
        <button type="submit">Sign In</button>
      </form>

      {error && <p>{error}</p>}
    </>
  );
}

And in the api:

import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';

export async function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseData>
) {
  const jsonBody = await request.json();
  const email = jsonBody.email;
  const password = jsonBody.password;
  const cookieStore = cookies();
  const supabase = createRouteHandlerClient({ cookies: () => cookieStore });

  try {
    const { user, error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      return res.status(401).json({ message: 'Login failed. Please check your credentials.' })
    }
    return res.status(200).json({ message: 'Login successful' })
  } catch (error) {
    console.error('An error occurred:', error);
    return res.status(500).json({ message: 'An unexpected error occurred' })
  }
}

Sign up to request clarification or add additional context in comments.

5 Comments

@Casino Franco, I tried this but I am receiving errors on router.push(response.headers.get('Location')); as Argument of type 'string | null' is not assignable to parameter of type 'Url'. Type 'null' is not assignable to type 'Url' and on route.ts as return NextResponse.error('An error occurred', { status: 500 }); and the error is: Expected 0 arguments, but got 2. and I cannot also login, it just displays the error and I cannot see the cookie as it was not logged in
Oh sorry, I did an update, check if it works now
You probably didn't need all this redirect logic: if (response.status === 302) { ... } Just do a router.push('/some-route-you-want')
Let me update it again
@Cassino Franco, there is still some errors that exist. On the page, it shows An unexpected error occurred. and on the console POST http://localhost:3000/auth/login net::ERR_ABORTED 405 (Method Not Allowed) I have updated the post as wel

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.