Open asmajlovicmars opened 1 year ago
Hi @asmajlovicmars, thank you for opening this issue.
With Amplify JS v6 we provide an adapter for only Next.js, although the underlying generic adapters may be used with other frameworks. We will provide instructions of using the generic adapters with other frameworks soon, but for now II'll mark this as a feature request and follow up once the instructions are available.
@nadetastic same problem here looks like we have a situation that will break our production code and no way around it. is there a possibility that you can point me in the right direction for how to use the generic adapters?
Primarily, these modifications enable compatibility between SvelteKit and Amplify v6, supporting both client-side rendering (CSR) and server-side rendering (SSR). While the entire application has not been converted yet, and all edge cases have not been tested, this marks a progressive step towards full integration.
// signin.svelte
// ...
import amplifyConfig from '../../amplifyconfiguration.json';
Amplify.configure({ Auth: authConfig }, { ssr: true }); // ssr: true will enable creation of cookies
await signIn({username: '...', password: '...'}); // will create CognitoIdentity jwt cookies
invalidateAll() // or use a milder version, just to make a new request, and trigger hooks
// ...
// hooks.server.ts
import type { Handle } from '@sveltejs/kit';
import amplifyConfig from '../../amplifyconfiguration.json';
import { Amplify } from 'aws-amplify';
// import { getCookiePayload, getSpecificCookie } from '$lib/utils/cookie-helpers';
type Cookie = { name: string; value: string } | null;
const getSpecificCookie = (cookies: any, name: string) =>
cookies
.map((cookie: Cookie) => (cookie?.name?.endsWith(name) ? cookie?.value : null))
.filter((value: string) => value !== null)[0];
const getCookiePayload = (cookie: string) => {
const payload = cookie?.split('.')[1];
const parsedPayload = JSON.parse(atob(payload));
return parsedPayload;
};
Amplify.configure(amplifyConfig, { ssr: true }); // not sure if { ssr: true } is a must, or needed here...
export const handleUser = (async ({ event, resolve }): Promise<Response> => {
const { request, cookies, locals, getClientAddress } = event;
const allCookies = cookies.getAll();
const cognitoCookies = allCookies.filter(
(cookie) => cookie.name.startsWith('CognitoIdentityServiceProvider') && cookie.value !== null
);
if (cognitoCookies?.length === 0) {
locals.jwtAccessToken = null;
locals.jwtIdToken = null;
locals.idTokenPayload = null;
locals.accessTokenPayload = null;
locals.userId = null;
locals.username = null;
locals.email = null;
locals.userGroups = null;
console.log('❌ no cookies:');
return resolve(event);
}
const idToken = getSpecificCookie(cognitoCookies, 'idToken');
const accessToken = getSpecificCookie(cognitoCookies, 'accessToken');
const idTokenPayload = idToken && getCookiePayload(idToken);
const accessTokenPayload = accessToken && getCookiePayload(accessToken);
locals.jwtAccessToken = accessToken;
locals.jwtIdToken = idToken;
locals.idTokenPayload = idTokenPayload;
locals.accessTokenPayload = accessTokenPayload;
locals.userId = idTokenPayload?.sub;
locals.username = idTokenPayload?.sub;
locals.email = idTokenPayload?.email;
locals.userGroups = idTokenPayload?.['cognito:groups'];
console.log('✅ signed-in email:', locals.email);
return resolve(event);
}) satisfies Handle;
// +layout.svelte or any other +page.svelte
<script lang="ts">
import { fetchAuthSession, getCurrentUser } from '@aws-amplify/auth';
import { Amplify, type ResourcesConfig } from 'aws-amplify';
import amplifyConfig from '../amplifyconfiguration.json';
import type { LayoutData } from './$types';
import { onMount } from 'svelte';
export let data: LayoutData;
const authConfig: ResourcesConfig['Auth'] = {
Cognito: {
userPoolId: amplifyConfig.aws_user_pools_id,
userPoolClientId: amplifyConfig.aws_user_pools_web_client_id
}
};
Amplify.configure({ Auth: authConfig}, { ssr: true });
onMount(async () => {
await fetchAuthSession(); // will refresh tokens!!! 🎉
});
</script>
<nav>
<ul class="horizontal-nav">
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/signin">Sign In</a>
</li>
</ul>
</nav>
<slot />
@asmajlovicmars thank you for your request. To improve the SSR experience in V6, we have moved to an adapter pattern that requires a custom implementation per framework. While we have shipped V6 with a Next.js adapter built-in, we would love to support more. In the next few days we are going to publish a document about the adapter with an example of how to build one. We are treating this issue as priority and will get back to you once we have the document published.
Thank you, @swaminator! I'm progressing through the migration from version 5 to 6, and things are improving. However, it would be much easier and more efficient to use a dedicated Vite/SvelteKit adapter. I'm looking forward to it, especially since we've committed to using both Amplify and SvelteKit, and not giving up 😁
Hi @asmajlovicmars @taoatmars following up here - we have published documentation on how to use the generic adapters and can be viewed here - https://docs.amplify.aws/react/build-a-backend/server-side-rendering/
Let me know if you have any questions.
This is excellent! Thank you @nadetastic. Will test ASAP.
@nadetastic, @swaminator Thank you both!
Just two corrections in the docs, getCurrentUser import on line 8, and line 57 should be called with the context:
line 8: import { fetchAuthSession, getCurrentUser } from 'aws-amplify/auth/server';
line 57: const { username } = await getCurrentUser(contextSpec);
hi, I'm trying to have calls to my backend in asp.net and from my angular application. I understand the documentation and the sample on here, however, I'm unsure how to make the calls with the amplify auth token on the first load of the page, I understand that behind the scenes a cookie is being set and the server uses the provider to get said cookie (that has auth tokens).
my first question: are all of the calls that needs to return user specific context all needs to be wrapped with the "runWithAmplifyServerContext" from the client side? Or did I misunderstood something here, does "runWithAmplifyServerContext" replace Amplify.configure() ?
second question: my ssr provider is angular ssr, however my backends that needs to provide user context are in ASP.net core, do I need to create a custom solution that extracts cookies from http requests if I was to onboard with what's happening here?
would love it if I can get some clarity on if this solution helps my case or I need to implement something on my own for this
I don't know if it addresses with this issue specifically, but there is now a SvelteKit Amplify adapter: https://github.com/gzimbron/amplify-adapter. If there are any issues, it'd be great to solve them there so that folks don't have to re-invent the wheel. The full list of adapters is available on https://www.sveltesociety.dev/packages?category=sveltekit-adapters - a few platforms have multiple adapters available
If anyone from AWS is interested in adding official first-party support for SvelteKit, please ping me and I'd be happy to add you to SvelteKit's partners program so that you can get direct support from the maintainers in supporting your integration
@benmccann The amplify-adapter does not include methods for handling server side cookies or generating the server side API method.
Hi @asmajlovicmars @taoatmars following up here - we have published documentation on how to use the generic adapters and can be viewed here - https://docs.amplify.aws/react/build-a-backend/server-side-rendering/
Let me know if you have any questions.
Have the docs changed ? I don't see a guide for generic implementation
Hi @dlamon1 apologies for the inconvenience, the documentation about the generic SSR adapter currently is available under the "Gen1" selector: https://docs.amplify.aws/gen1/react/build-a-backend/server-side-rendering/
Before opening, please confirm:
JavaScript Framework
Web Components
Amplify APIs
Authentication, GraphQL API
Amplify Categories
auth
Environment information
Describe the bug
I'm excited about the v6, and started testing a migration, but quickly got stuck on SSR side.
// v5 - server side - this used to work seamlessly
Now I'm trying to get it going with v6 on the server side, and not sure how to do it:
However, on the V6 client side, everything works as expected:
Expected behavior
Expected behaviour is that the server side authenticates, and provides a cognitoUser same as in V5.
Reproduction steps
Code Snippet
I'm excited about the v6, and started testing a migration, but quickly got stuck on SSR side.
// v5 - server side - this used to work seamlessly
Now I'm trying to get it going with v6 on the server side, and not sure how to do it:
However, on the V6 client side, everything works as expected:
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response