Handling Signin and Signout of Auth.js

Auth.js is very flexible. Usage of learning is very happy.

I integrate my user password postgres database by CredentialsProvider. The key is custom sign in and sign out page and fetch csrfToken.

My vike-server primary codes:

// pages/logout/+Page.tsx

export default Page
import { FormEvent, useEffect, useState } from 'react';
import { reload } from 'vike/client/router';
import { Box, Button, Title } from '@mantine/core';

function Page() {
  const [ csrfToken, setCsrfToken] = useState<string>('');
  useEffect(() => {
    fetch('/api/auth/csrf', {
      method: 'GET',
    }).then(response => {
      if (response.ok) {
        return response.json();
      }
    }).then(res => {
      setCsrfToken(res.csrfToken);
      console.log('res.csrfToken=' + res.csrfToken);
    });
  }, []);

  const handleSubmit = async (ev: FormEvent) => {
    ev.preventDefault();
    const response = await fetch('/api/auth/signout', {
      method: 'POST',
      body: JSON.stringify({ csrfToken }),
      headers: [['Content-Type', 'application/json']],
    })
    await reload();
  };

  return (
    <Box style={{ overflow: 'hidden' }}>
      <Title>Log out</Title>
      <form onSubmit={handleSubmit} style={{ marginTop: 10 }}>
        <Button variant="filled" type="submit" style={{ marginTop: 20 }}>
          Logout
        </Button>
      </form>
    </Box>
  )
}
// pages/login/+Page.tsx

export default Page
import { FormEvent, useEffect, useState } from 'react'
import { reload } from 'vike/client/router'
import { Box, Button, PasswordInput, TextInput, Title } from '@mantine/core';

function Page() {
  const [ password, setPassword] = useState<string>('');
  const [ passwordError, setPasswordError] = useState<string>('');
  const [ username, setUsername] = useState<string>('');
  const [ usernameError, setUsernameError] = useState<string>('');
  const [ csrfToken, setCsrfToken] = useState<string>('');
  useEffect(() => {
    fetch('/api/auth/csrf', {
      method: 'GET',
    }).then(response => {
      if (response.ok) {
        return response.json();
      }
    }).then(res => {
      setCsrfToken(res.csrfToken);
    });
  }, []);

  const handleSubmit = async (ev: FormEvent) => {
    ev.preventDefault();
    if (username.length > 0 && password.length > 19) {
      setPasswordError('');
      setUsernameError('');
      const response = await fetch('/api/auth/callback/credentials', {
        method: 'POST',
        body: JSON.stringify({ csrfToken, username, password }),
        headers: [['Content-Type', 'application/json']],
      });
      const params = (new URL(response.url))?.searchParams;
      if (params?.get('error') === 'CredentialsSignin') {
        setPasswordError('Login error! Please check username and password.');
      } else if (response.ok) {
        await reload();
      } else {
        setPasswordError('Login error.');
      }
    } else {
      if (password.length <= 19) {
        setPasswordError('Password length need more than 19 chars.');
      } else {
        setPasswordError('');
      }
      if (username.length == 0) {
        setUsernameError('Username is blank.');
      } else {
        setUsernameError('');
      }
    }
  };

  return (
    <Box style={{ overflow: 'hidden' }}>
      <Title>Log in</Title>
      <form onSubmit={handleSubmit} style={{ marginTop: 10 }}>
        <TextInput label="username" onChange={(event) => setUsername(event.currentTarget.value)} error={usernameError} />
        <PasswordInput label="password" onChange={(event) => setPassword(event.currentTarget.value)} error={passwordError} />
        <Button variant="filled" type="submit" style={{ marginTop: 20 }}>
          Login
        </Button>
      </form>
    </Box>
  )
}

Hope these are useful to learning vike-server and Auth.js.

238

Top articles