feat: 完整注册登录注销流程

This commit is contained in:
sealday 2024-04-05 15:35:01 +08:00
parent de010862f4
commit 5c6b5b9761
8 changed files with 95 additions and 10 deletions

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"typescript.suggest.paths": false,
"javascript.suggest.paths": false,
}

View File

@ -0,0 +1,11 @@
'use client';
import { signout } from '@/app/lib/actions';
export default function SignoutButton() {
return <button onClick={async () => {
await signout();
}}>
</button>
};

View File

@ -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;
}
}
} */

View File

@ -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
View File

@ -0,0 +1,3 @@
export default function Page() {
return <main>hello world</main>
}

View File

@ -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&nbsp;

View File

@ -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
View 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$).*)'],
}