getServerSession works in one component but not another on the same page
Unanswered
Asian black bear posted this in #help-forum
Asian black bearOP
I have a component for profile images for a variety of components from tables from search results, thumbnails in a family view and then the individual profiles.
I thought I could cleanup my code by putting all the code into an API endpoint to hit the AWS server. However
Any initial hunches on what would cause this behavior?
I thought I could cleanup my code by putting all the code into an API endpoint to hit the AWS server. However
getServerSession seems to work in some components but not others. Any initial hunches on what would cause this behavior?
29 Replies
Asian black bearOP
I got it narrowed down to getServerSession returning null
for visual context - the images are hitting the same endpoint
@Asian black bear I got it narrowed down to getServerSession returning null
can you show the code where you use
getServerSession?Asian black bearOP
my code is a mess at the moment as I was trying to break functions down to debug but the profile images is
API endpoint
API endpoint
import type { NextApiRequest, NextApiResponse } from "next";
import axios, { type AxiosRequestConfig } from "axios";
import { type MembersImageType } from "../../../server/serverTypes";
import { getServerAuthSession } from "~/server/auth";
import { broHeadshot } from "~/components/ui-library/images/headshots";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<string | { error: string }>
) {
if (req.method === "GET") {
let session;
try {
session = await getServerAuthSession({ req, res });
} catch (error) {
console.log(error);
res.status(500).json({ error: "Failed to get server auth session" });
return;
}
let accessToken;
let configImageURL;
let configImageGet: AxiosRequestConfig;
const { id } = req.query;
const imageResToURL = (res: MembersImageType[]): string => {
const filteredObject = res.filter((obj) => obj.main_photo === 1)[0];
if (!filteredObject) return "";
const photoURL = filteredObject.photo_loc.replace(".thumb", "");
return photoURL;
};
const baseAPIURL =
process.env.xxxx ||
"https://xxxxxxx.execute-api.us-east-1.amazonaws.COM";
if (session) {
accessToken = session.accessToken;
configImageURL = {
headers: {
Authorization: accessToken,
},
};
configImageGet = {
headers: {
Authorization: accessToken,
"content-type": "image/jpeg",
},
responseType: "arraybuffer",
};
try {
const response1 = await axios.get<MembersImageType[]>(
`${baseAPIURL}/members/${id as string}/images`,
configImageURL
);
const imageURL = imageResToURL(response1.data);
const response2 = await axios.get<string>(
`${baseAPIURL}/images/${imageURL}`,
configImageGet
);
const imageBuffer = Buffer.from(response2.data, "base64");
const imageBufferString = imageBuffer.toString("base64");
const imageSrc = `data:image/jpeg;base64, ${imageBufferString}`;
res.status(200).json(imageSrc);
} catch (error) {
console.log(error);
res.status(200).json(broHeadshot);
}
} else {
res.status(400).json({ error: "Session must be provided" });
}
} else {
res.setHeader("Allow", ["GET"]);
res.status(405).json({ error: `Method ${req.method!} Not Allowed` });
}
}can you show the code of
getServerAuthSession?Asian black bearOP
just a wrapper provided from T3stack
/**
* Wrapper for `getServerSession` so that you don't need to import the `authOptions` in every file.
*
* @see https://next-auth.js.org/configuration/nextjs
*/
export const getServerAuthSession = (ctx: {
req: GetServerSidePropsContext["req"];
res: GetServerSidePropsContext["res"];
}) => {
return getServerSession(ctx.req, ctx.res, authOptions);
};I had the above wrapped in
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { broHeadshot } from "~/components/ui-library/images/headshots";
import { type FetchMemberImageByIdProps } from "~/server/fetchImages";
import { baseURL } from "./config";
export const getProfileImage = async ({
idString,
}: FetchMemberImageByIdProps) => {
if (!baseURL) {
return;
}
const queryURL = `${baseURL}/api/profile_images/${idString}`;
try {
const response = await fetch(queryURL);
const data = await response.json(); // or .json() if the response is JSON
return data as string;
} catch (error) {
return broHeadshot;
}
};Asian black bearOP
currently all in
getServerSideProps@Asian black bear for visual context - the images are hitting the same endpoint
can you show the code for this page?
@Asian black bear for visual context - the images are hitting the same endpoint
the problem is the second image cannot be shown?
Asian black bearOP
it's a little round about but we're hitting a legacy database for member info and then putting it through this function to map API response to component props. This is also where we have info from the API to query the AWS bucket for the profile image.
import {
getDepartmentMap,
getRelationshipMap,
getSundayWorshipMap,
roleTitleCodeMap,
} from "helper/chadminDBDefinitions";
import {
type PersonType,
type MembersApiItem,
} from "../src/server/serverTypes";
import { getProfileImage } from "./getProfileImage";
import { broHeadshot } from "~/components/ui-library/images/headshots";
import { formattedDate } from "./formatDate";
export type PartialPersonType = Partial<PersonType>;
export const apiToMemberProps = async (
member: MembersApiItem,
token: string
): Promise<PartialPersonType> => {
let profileImage;
if (member.member_id) {
profileImage = await getProfileImage({
idString: member.member_id,
token,
});
} else {
profileImage = broHeadshot as string;
}
const englishFullName = `${member?.name_efirst} ${member?.name_elast}` || "";
return {
image: {
imageUrl: profileImage || broHeadshot,
},
info: {
"English Name": englishFullName || null,
"Korean Name": `${member?.name_klast}${member?.name_kfirst}` || null,
Gender: member?.sex || "N/A",
Birthday: formattedDate(member?.birthday) || null,
Ministry: getDepartmentMap(member?.dept_id) || null,
"Sunday Worship": getSundayWorshipMap(member?.sn_tag) || null,
"Ministry Role": roleTitleCodeMap(member?.position_cd) || null,
"Family ID": member?.family_id || null,
Relationship: getRelationshipMap(member?.relation_cd) || null,
"Member Type": member?.member_type || null,
"Membership Tag": member?.member_tag?.trim() || null,
Title: member?.title_cd || null,
"Soon Name": "pending",
"Registration Date": formattedDate(member?.enroll_dt) || null,
Address: member?.addr || null,
City: member?.city || null,
State: member?.state || null,
Zip: member?.zip || null,
Phone: member?.phone1 || member?.phone2 || member?.phone3 || null,
Email: member?.email1 || null,
"Entry Id": member?.member_id || null,
Note: member?.note || null,
},
};
};don't mind the token - left over from when we were passing it around manually before we found out about getServerSession 

Asian black bearOP
so I use the same function
for all three applications - search result tables, individual profiles, family profiles
Asian black bearOP
export const getServerSideProps: GetServerSideProps = async (context) => {
const session = await getSession(context);
const token = session?.accessToken as string;
const { id } = context.params ?? {};
const idString = id as string;
const profileRaw = await fetchMemberById({ id: idString, token });
const memberProfile = await apiToMemberProps(profileRaw[0]!, token);
let familyArray: MembersApiItem[] = [];
if (memberProfile.info?.["Family ID"] != null) {
familyArray = await fetchFamilyList({
idString: memberProfile.info?.["Family ID"],
token,
});
}so note
memberProfile hits apiToMemberProps and fetchFamilyList also calls apiToMemberProps under the hood@Asian black bear export const getServerSideProps: GetServerSideProps = async (context) => {
const session = await getSession(context);
const token = session?.accessToken as string;
const { id } = context.params ?? {};
const idString = id as string;
const profileRaw = await fetchMemberById({ id: idString, token });
const memberProfile = await apiToMemberProps(profileRaw[0]!, token);
let familyArray: MembersApiItem[] = [];
if (memberProfile.info?.["Family ID"] != null) {
familyArray = await fetchFamilyList({
idString: memberProfile.info?.["Family ID"],
token,
});
}
oh I think you should use
getServerSession instead of getSession here?Asian black bearOP
but the API endpoint pulls session on its own? I was hoping to trying to stop drilling token down everywhere haha
@Asian black bear but the API endpoint pulls session on its own? I was hoping to trying to stop drilling token down everywhere haha
sorry wdym? you cant get token from the session return from
getServerSession?Asian black bearOP
no originally the component worked that way but I'm trying to refactor so I'm not passing the token around to so many components and relying on the API call to have access to
getServerAuthSession instead. whats weird is that one implementation works and the other doesn't@Asian black bear no originally the component worked that way but I'm trying to refactor so I'm not passing the token around to so many components and relying on the API call to have access to `getServerAuthSession` instead. whats weird is that one implementation works and the other doesn't
can you show your nextauth config where you setup the token?
Asian black bearOP
@Asian black bear Click to see attachment
can you add a
console.log(token) to the jwt callback and see if it look different with getSession and getServerAuthSession?Asian black bearOP
callback has same logs. One thing that is interesting I noticed in the axios error was the following: Note that the queried URL is NaN. this only seems to be the case when queriying for the family list
config: {
transitional: [Object],
adapter: [Array],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: [Function: validateStatus],
headers: [Object [AxiosHeaders]],
method: 'get',
url: 'https://xxxx.execute-api.us-east-1.amazonaws.com/members/NaN',
data: undefined
},