JS3*_*JS3 5 javascript typescript reactjs next.js supabase
我有这个/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,
})
}
Run Code Online (Sandbox Code Playgroud)
以及/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>
</>
)
}
Run Code Online (Sandbox Code Playgroud)
这些是我从文档中获得的代码。但是,我无法实现显示他们已成功登录的位置以及错误处理。
我遵循了下面的答案,但是,我收到了此错误:
POST http://localhost:3000/auth/login net::ERR_ABORTED 405(方法不允许)
路由.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' });
}
}
Run Code Online (Sandbox Code Playgroud)
api/登录/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>}
</>
);
}
Run Code Online (Sandbox Code Playgroud)
我看到您确实在 Next.js 中为端点实现了一个路由处理程序/auth/login,但在您的第一个代码片段中,您定义了一个名为 的函数POST。在第二个片段中,您已将此函数重命名为handler. 在两个代码片段中对此函数使用相同的名称会更清楚。
由于您收到 405,我认为服务器配置或路由处理程序未正确设置以处理对此端点的 POST 请求。
首先,确保路由处理程序的文件名与您尝试处理的 URL 路径匹配。例如,如果您的路由处理程序位于名为 的文件中route.ts,请确保它位于pages/api/auth/login/route.ts您的项目目录中。
将路由处理程序函数导出为路由处理程序文件中的默认导出。
// pages/api/auth/login/route.ts
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// rest of your code
}
Run Code Online (Sandbox Code Playgroud)
另外,请确保您的路由处理程序正确处理 POST 请求。您可以使用该req.method属性检查传入请求的 HTTP 方法并做出相应响应。
if (req.method === 'POST') {
// Handle POST requests
// rest of your code for handling POST requests
} else {
// Respond with a 405 Method Not Allowed if the request is not a POST request
res.status(405).send('Method Not Allowed');
}
Run Code Online (Sandbox Code Playgroud)
根据这些建议,代码将是:
route.ts):// pages/api/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) {
// Parse JSON body from the request
const jsonBody = await request.json();
const { email, password } = jsonBody;
const cookieStore = cookies();
const supabase = createRouteHandlerClient({ cookies: () => cookieStore });
try {
const { error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) {
// Return a JSON response with a 401 status code for unauthorized
return NextResponse.json({ message: 'Login failed. Please check your credentials.' }, { status: 401 });
}
// Return a JSON response indicating success
return NextResponse.json({ message: 'Login successful' });
} catch (error) {
console.error('An error occurred:', error);
// Return a JSON response with a 500 status code for server error
return NextResponse.json({ message: 'An unexpected error occurred' }, { status: 500 });
}
}
Run Code Online (Sandbox Code Playgroud)
page.tsx):// pages/app/login/page.tsx
import { useRouter } from 'next/router';
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('/api/auth/login/route', { // Corrected the URL to match the route handler file location
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')) {
const result = await response.json();
setError(result.message);
} else {
setError('An unexpected error occurred.');
}
}
} 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>}
</>
);
}
Run Code Online (Sandbox Code Playgroud)
在路由处理程序 ( route.ts) 中,我添加了一个检查以确保请求方法是使用 POST 的if (req.method !== 'POST')。
在登录页面 ( page.tsx) 中,我修复了函数中的 URLfetch以匹配路由处理程序文件 ( ) 的位置/api/auth/login/route。
全部流程:
+-----------------------+ User Input +------------------------+
| | -------------> | |
| Client: | (email, | Server: |
| pages/app/login/ | password) | pages/api/auth/login/ |
| page.tsx | | route.ts |
| | | |
| 1. Render Login Page | | |
| | | |
| 2. User submits | | |
| form | | |
| | | |
| 3. handleSubmit | POST Req. | 4. POST function |
| triggers fetch | -------------> | executes: |
| request to server | | |
| | | - Parse request |
| | | - Authenticate |
| | | via Supabase |
| | | - Prepare response |
| | | |
+-----------------------+ Response +------------------------+
<-------------
(success/error msg) | | (success/error msg)
| |
+-----------------------+ |
| | |
| Client: | |
| pages/app/login/ | |
| page.tsx | |
| | |
| 5. Process response: | |
| - Success: Redirect| |
| to homepage | |
| - Failure: Display | |
| error message | |
| | |
+-----------------------+ |
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
395 次 |
| 最近记录: |