#After login, how to get stored cookie/localStorage data into server component?

44 messages · Page 1 of 1 (latest)

prime abyss
#

Thanks @muted pilot for helping me out in my last question about Login with server component.

Now I am able to store the tokens I need, idToken, personId into cookies or localStorage from the login-form client component. Next I redirect to /postings, which loads up my postings/page server component.

And that page component needs to get a fetch from another server component fetchPostings.

I'm able to set the cookies and localStorage, but unable to fetch the required tokens from page and send them into fetchPostings to make the next call.

I read that js-cookies would let me solve that, but the tokens are undefined, I tried cookies from next/headers, but got an error saying I can't do that.

Is there another way to pass those tokens after login into server components for another call?

The only other thing I can think of is while I'm in the login server component, to go ahead and make that getUserPostings call there, then passing everything into the login-form client component to pass on.

My postings/page (server component)

import Cookies from 'js-cookie';
// import { cookies } from 'next/headers';

import PostingsList from '@/components/postings/postings-list';
import fetchPostings from '@/services/postings';

export default async function Postings() {
  let postingsData = [];
  let errorMessage;
  const cookies = new Cookies();
  // const cookieStore = cookies();

  const idToken = cookies.get('idToken') ?? '';
  const personId = cookies.get('personId') ?? '';

  // console.log('idToken', idToken);
  // console.log('personId', personId);


  try {
    postingsData = await fetchPostings(idToken, personId);
    console.log('postingsData', postingsData);
  } catch (error: any) {
    errorMessage = error.message;
  }

  return (
    <>
      <PostingsList postings={postingsData} errorMessage={errorMessage} />
    </>
  );
};

My fetchPostings (server component)

'user server';
import { API_GET_POSTINGS, METHOD_GET } from '@/constants';

const fetchPostings = async (idToken: string, personId: string) => {

  const generateSearchParams = () => {
    const params = new URLSearchParams();
    params.append('posting-state', 'all');
    params.append('page', '1');
    params.append('page-size', '5');
    return params;
  };

  const params = generateSearchParams();
  try {
    const response = await fetch(API_GET_POSTINGS(personId || '', params), {
      ...METHOD_GET,
      headers: {
        Authorization: idToken || '',
      },
    });

    if (!response.ok) {
      throw new Error(`Error fetching postings: ${response.statusText}`);
    }

    const data = await response.json();
    console.log('fetching postings data:', data);
    return data;
  } catch (error: any) {
    console.error(error);
    return error;
  }
};

export default fetchPostings;

my login-form (client component)

Where I save the cookies/localStorage

// ? store idToken in redux
   if (idToken) {
     cookies().set('idToken', idToken);
     localStorage.setItem('idToken', idToken);
   }
unique basinBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

muted pilot
prime abyss
#

Ok yes I did get that to work now thanks 🙂

const personId = allCookies.find(cookie => cookie.name === 'personId');
  const idToken = allCookies.find(cookie => cookie.name === 'idToken');
#

I'm running into this error tho

Error: Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.

But need to fix something and try again

muted pilot
#

I think you need

const personId = allCookies.find(cookie => cookie.name === 'personId') ?? '';
  const idToken = allCookies.find(cookie => cookie.name === 'idToken') ?? '';
prime abyss
#

Yes thats what I have, but now I keep running into this

Error: 
  × You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/
  │ react-essentials#server-components

I'm using cookies from next/headers in my login client component, going to try use js-cookies there again.

Just strange I have to use 2 different cookie libs

muted pilot
prime abyss
#

yes I do, but I can't get to localStorage from my server component, or at least, I don't know how

muted pilot
#

if so, just read from there in the client component, so you don't need to use cookies()

prime abyss
#

But I have to make all my calls from server components now

#

The reason is

#
  1. we hide the API key
  2. avoid CORs issues
#

So I login, I save the cookies and localStorage

muted pilot
prime abyss
#

Next I route to /postings, and I need to GET postings, but with those vars I saved

#

Oh no ignore the login component, I'm using cookie logic there to SAVE the cookies

#

sec going to try again

#

Willing to screenshare? 😄 I can pay for some time via CashApp or Bitcoin

muted pilot
#

liveshare?

prime abyss
#

yeah

#

discord call or google meet

muted pilot
#

vscode extension lol

prime abyss
#

oh

#

ok I have it installed how do I use it?

#

ah crap I'm hiding the status bar 1 sec

#

can you see my other tabs? or just this one?

muted pilot
#

try again

#

fetching

prime abyss
#

same error

Uncaught Error: Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.

prime abyss
#

forbidden I'll login again real quick

#

oh wait, no more error now

#

the Postings call is forbidden but app doesn't break hmm

#
 ⨯ Error: Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.
    at stringify (<anonymous>)
queryString: ?posting-state=all&page=1&page-size=5
response.status 403
Error: Error fetching postings: Forbidden
#

ok I still see Forbidden, so it may be our Backend issue

#

but ok so that Only Plain Objects error, I don't get that message in the browser anymore, only in the terminal, which is better?

#

Thanks! Getting closer

muted pilot
prime abyss
#

gotcha, throw it instead

#

Appreciate it

prime abyss
#

This is solved now, again thanks! 😄