feat: 完整注册登录注销流程
This commit is contained in:
parent
de010862f4
commit
5c6b5b9761
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"typescript.suggest.paths": false,
|
||||
"javascript.suggest.paths": false,
|
||||
}
|
11
app/components/signout-button.tsx
Normal file
11
app/components/signout-button.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
'use client';
|
||||
import { signout } from '@/app/lib/actions';
|
||||
|
||||
export default function SignoutButton() {
|
||||
return <button onClick={async () => {
|
||||
|
||||
await signout();
|
||||
}}>
|
||||
注销
|
||||
</button>
|
||||
};
|
@ -2,7 +2,7 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
/* :root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
@ -30,4 +30,4 @@ body {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
} */
|
@ -1,12 +1,55 @@
|
||||
'use server';
|
||||
import axios from "axios";
|
||||
import { redirect } from 'next/navigation'
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
const SIGNUP_URL = 'https://tachy.daoyoucloud.com/api/auth:signUp';
|
||||
// const SIGNUP_URL = 'http://127.0.0.1:13000/api/auth:signUp';
|
||||
const SIGNIN_URL = 'https://tachy.daoyoucloud.com/api/auth:signIn';
|
||||
const SIGNOUT_URL = 'https://tachy.daoyoucloud.com/api/auth:signOut'
|
||||
|
||||
|
||||
export async function authenticate(_currentState: unknown, formData: FormData) {
|
||||
return '';
|
||||
export async function signout() {
|
||||
const token = cookies().get('token');
|
||||
const result = await fetch(SIGNOUT_URL, {
|
||||
"headers": {
|
||||
"authorization": "Bearer " + token?.value,
|
||||
"cache-control": "no-cache",
|
||||
"pragma": "no-cache",
|
||||
"x-app": "danmu-sim",
|
||||
"x-authenticator": "basic",
|
||||
"x-locale": "zh-CN",
|
||||
"x-timezone": "+08:00",
|
||||
"x-with-acl-meta": "true",
|
||||
},
|
||||
"body": '',
|
||||
"method": "POST"
|
||||
});
|
||||
cookies().delete('token');
|
||||
redirect('/signin');
|
||||
}
|
||||
|
||||
|
||||
export async function signin(_currentState: unknown, formData: FormData) {
|
||||
const result = await fetch(SIGNIN_URL, {
|
||||
"headers": {
|
||||
"cache-control": "no-cache",
|
||||
"content-type": "application/json",
|
||||
"pragma": "no-cache",
|
||||
"x-app": "danmu-sim",
|
||||
"x-authenticator": "basic",
|
||||
"x-hostname": "tachy.daoyoucloud.com",
|
||||
"x-locale": "zh-CN",
|
||||
"x-timezone": "+08:00",
|
||||
"x-with-acl-meta": "true",
|
||||
},
|
||||
"body": JSON.stringify(Object.fromEntries(formData)),
|
||||
"method": "POST"
|
||||
});
|
||||
const res = await result.json();
|
||||
if (res.errors) {
|
||||
return res.errors[0].message;
|
||||
}
|
||||
cookies().set('token', res.data.token);
|
||||
redirect('/');
|
||||
}
|
||||
|
||||
export async function signup(_currentState: unknown, formData: FormData) {
|
||||
|
3
app/music/page.tsx
Normal file
3
app/music/page.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <main>hello world</main>
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
import Image from "next/image";
|
||||
import SignoutButton from "@/app/components/signout-button";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
||||
<SignoutButton />
|
||||
<Link className="btn" href="/music">弹幕测试</Link>
|
||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
||||
Get started by editing
|
||||
|
@ -1,14 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import { authenticate } from '@/app/lib/actions'
|
||||
import { signin } from '@/app/lib/actions'
|
||||
import { useFormState, useFormStatus } from 'react-dom'
|
||||
|
||||
export default function Page() {
|
||||
const [errorMessage, dispatch] = useFormState(authenticate, undefined)
|
||||
const [errorMessage, dispatch] = useFormState(signin, undefined)
|
||||
|
||||
return (
|
||||
<form action={dispatch}>
|
||||
<input type="email" name="email" placeholder="Email" required />
|
||||
<input name="account" placeholder="Account" required />
|
||||
<input type="password" name="password" placeholder="Password" required />
|
||||
<div>{errorMessage && <p>{errorMessage}</p>}</div>
|
||||
<LoginButton />
|
||||
@ -19,7 +19,7 @@ export default function Page() {
|
||||
function LoginButton() {
|
||||
const { pending } = useFormStatus()
|
||||
|
||||
const handleClick = (event) => {
|
||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
if (pending) {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
20
middleware.ts
Normal file
20
middleware.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import type { NextRequest } from 'next/server'
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
const currentUser = request.cookies.get('token')?.value
|
||||
|
||||
if (currentUser && !request.nextUrl.pathname.startsWith('/')) {
|
||||
return Response.redirect(new URL('/', request.url))
|
||||
}
|
||||
|
||||
if (!currentUser
|
||||
&& !request.nextUrl.pathname.startsWith('/signin')
|
||||
&& !request.nextUrl.pathname.startsWith('/signup')
|
||||
) {
|
||||
return Response.redirect(new URL('/signin', request.url))
|
||||
}
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
|
||||
}
|
Loading…
Reference in New Issue
Block a user