NextJS with external Authentication API
Unanswered
Korat posted this in #help-forum
KoratOP
After I lot of tries and difficulties using next auth, I finally switched to implementing my own simple logic,
It's because I already have an external API that handles the authentication and authorization part.
So, on login, using a server action, i send a request to my real api which returns me the user data and JWT token.
After that I save those inside an httponly cookie and I move the user data into zustands state using a custom provider.
The problem occurs when I need to send the jwt inside Authorization header request that needs the token. What I did is inside my fetch wrapper, i get the token from cookies and move the token forward inside the authroization header.
I talked with @aardani and he gave me a nice idea (to use next server as a proxy).
This means that I add 'use server' to all mutations and queries files.
But with this approach, the issue comes when using queries in client side components (sometimes inputs inside forms need data from an external api to be filled with).
In this case I tried to use react query's useQuery but I don't get any data.
Im out of ideas and I would love to get your help on this.
It's because I already have an external API that handles the authentication and authorization part.
So, on login, using a server action, i send a request to my real api which returns me the user data and JWT token.
After that I save those inside an httponly cookie and I move the user data into zustands state using a custom provider.
The problem occurs when I need to send the jwt inside Authorization header request that needs the token. What I did is inside my fetch wrapper, i get the token from cookies and move the token forward inside the authroization header.
I talked with @aardani and he gave me a nice idea (to use next server as a proxy).
This means that I add 'use server' to all mutations and queries files.
But with this approach, the issue comes when using queries in client side components (sometimes inputs inside forms need data from an external api to be filled with).
In this case I tried to use react query's useQuery but I don't get any data.
const { data } = useQuery({
queryKey: ['car-brands'],
queryFn: async () => await getCarBrands(),
});'use server';
import { client } from '@/lib/client';
/**
* get the list of cars
* @returns
*/
export const getCarBrands = async () => {
const response = await client<{ id: string; name: string }[]>('cars/brands', {
method: 'GET',
next: { tags: ['cars-brands'] },
});
console.log(response);
return response;
};Im out of ideas and I would love to get your help on this.
13 Replies
In this case I tried to use react query's useQuery but I don't get any data.
Can you debug it?
what went wrong?
did the client made a request to the Next.js server?
did Next.js server received the request?
did the fetch succeeded?
what is the error log?
@aardani did the client made a request to the Next.js server?
KoratOP
Seems like the server action is not being ran,
I tried to make a fetch on another project and it worked nice,
Might there be any issue with how the component is used ?
I tried to make a fetch on another project and it worked nice,
Might there be any issue with how the component is used ?
KoratOP
I think i found something
this filter component is causing it somehow, when i comment it the server action runs
KoratOP
@aardani Inside of this I have a Search Field component, when i comment it, it works nice, i don't understand why this component is blocking a server actions query from inside another component
'use client';
import { useEffect, useTransition } from 'react';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { useDebounce } from '@/hooks/use-debounce';
import { Search } from 'lucide-react';
import { Input, InputProps } from '../ui/input';
export default function SearchField({ ...rest }: InputProps) {
/**
* @hooks
*/
const { replace } = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const [_, startTransition] = useTransition();
const [query, setQuery] = useDebounce('', 250);
/**
* @effects
*/
useEffect(() => {
handleSearch(query);
}, [query]);
/**
* @handlers
*/
function handleSearch(query: string) {
const params = new URLSearchParams(window.location.search);
if (query) params.set('q', query);
else params.delete('q');
startTransition(() => {
replace(`${pathname}?${params.toString()}`);
});
}
return (
<Input
id='search'
name='search'
startAdornment={<Search className='h-5 w-5 text-muted-foreground' />}
placeholder='Search'
defaultValue={searchParams.get('q') || ''}
onChange={(event) => setQuery(event.target.value)}
{...rest}
/>
);
}