skip to Main Content

im quite new to react and next js, i can do server side get request just fine, it is pretty simple. i just wanted to know how to execute a post request to an external api in NextJs server side, cause i dont wanna show the api url in the network console, but i dont get how to do it, cause with normal procedure i just have to put "use client" on top of the page

thats my code of a normal post request login, and it works perfectly fine, but in the network tab it is obviusly exploitable.

thanks all for the patience

"use client"

import Link from "next/link"

import { Button } from "@/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { useToast } from "@/components/ui/use-toast"
import { useState } from "react"
import { useRouter } from "next/navigation"
import { ModeToggle } from "@/components/mode-toggle"
import { useDispatch } from 'react-redux';
import { loginSuccess } from '../redux/authSlice';


const  LoginForm = () => {

  

    const { toast } = useToast()
  const [error, setError] = useState("");
  const router = useRouter();
  
  
  const [formData, setFormData] = useState({
    
    username: '',
    password: ''
  });
  

  const handleInputChange = (event:any) => {
    const { name, value } = event.target;
    setFormData({
      ...formData,
      [name]: value
    });
  };

  const handleSubmit = async (event:any) => {
    event.preventDefault(); 

    try {
      const response = await fetch('http://localhost:8080/api/auth/signin', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
      });
  
      const responseData = await response.json();
      
       
  
      // Verifica se la risposta contiene un messaggio di conferma
      if (responseData) {
        console.log('Login effettuato con successo!', responseData);
        localStorage.setItem('accessToken', responseData.token);
        localStorage.setItem('username', responseData.username);
        localStorage.setItem('isLoggedin', 'true');
        
        
        toast({
          description: "Login has been successful"
        })
        router.push('/');
        
        
        

        setFormData({
          
          username: '',
          password: ''
        });
        
      } else {
        // Altrimenti, la risposta non è come previsto
        console.error('La risposta dall'API non è come previsto:', responseData);
        setError('Credenziali non valide. Si prega di riprovare.');
        
      }
  
    } catch (error) {
      
      console.error('Errore durante la registrazione:', error);
    }
  };
  return (
    <>
    <div className="toggle absolute top-5 right-5">
    <ModeToggle></ModeToggle>
    </div>
    
    <Card className="mx-auto my-auto max-w-sm ">
      <CardHeader>
        <CardTitle className="text-6x1 font-bold">Login</CardTitle>
        <CardDescription>
          Enter your email below to login to your account
        </CardDescription>
      </CardHeader>
      <CardContent>
      
      <form onSubmit={handleSubmit}>
      {error && <p style={{ color: 'red' }}>{error}</p>} {/* Visualizza l'errore se presente */}
        
      <Label>
        Username:
        <Input  type="text" name="username" value={formData.username} onChange={handleInputChange} />
      </Label>
      
      
      <Label>
        Password:
        <Input  type="password" name="password" value={formData.password} onChange={handleInputChange} />
      </Label>
      
      <Button className='mt-4 w-full' variant={"default"} type="submit"> Sign Up</Button>
      <p className="font-bold text-sm mt-4">You are not registered yet? <Link href="/register"><Button className="size-sm" variant={"link"}>Register</Button></Link></p>
      
      
    </form>
      </CardContent>
    </Card>
    </>
  )
}


export default LoginForm;

2

Answers


  1. Checkout getServerSideProps

    Example

    
    import type { InferGetServerSidePropsType, GetServerSideProps } from 'next'
     
    type Repo = {
      name: string
      stargazers_count: number
    }
     
    export const getServerSideProps = (async () => {
      // Fetch data from external API
      const res = await fetch('https://api.github.com/repos/vercel/next.js')
      const repo: Repo = await res.json()
      // Pass data to the page via props
      return { props: { repo } }
    }) satisfies GetServerSideProps<{ repo: Repo }>
     
    export default function Page({
      repo,
    }: InferGetServerSidePropsType<typeof getServerSideProps>) {
      return (
        <main>
          <p>{repo.stargazers_count}</p>
        </main>
      )
    }
    

    Or if you’re using app router checkout data fetching

    async function getData() {
      const res = await fetch('https://api.example.com/...')
      // The return value is *not* serialized
      // You can return Date, Map, Set, etc.
     
      if (!res.ok) {
        // This will activate the closest `error.js` Error Boundary
        throw new Error('Failed to fetch data')
      }
     
      return res.json()
    }
     
    export default async function Page() {
      const data = await getData()
     
      return <main></main>
    }
    
    Login or Signup to reply.
  2. Check out server side actions and mutations
    https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations. You can write actions and directly call them inside client component. example is given in the doc, checkout createUser action.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search