Using Auth method to check if the user is logged in with SSR and then trying to signOut does not work
See original GitHub issueDescribe the bug
I’m using the Auth method to know if a user is logged in and then execute the signOut method to logout but does not work. Also, the Auth.currentAuthenticatedUser()
throws an error that the user is not authenticated even when it is on SSR. I have just implemented this on Dev, I haven’t tried on Prod.
To Reproduce
First, I have added the Amplify.configure({ ...config, ssr: true });
in the _app.js
file. Then, I created a function to detect if the a user is logged in when the getServerSideProps
is executed. This is withAuth
:
import { withSSRContext } from 'aws-amplify';
export const withAuth = async context => {
try {
const SSR = withSSRContext(context);
const user = await SSR.Auth.currentAuthenticatedUser();
return user;
} catch (error) {
context.res.writeHead(301, { Location: '/signin' });
context.res.end();
}
};
I call this function on every private page the project has, like this:
import React from 'react';
import { withAuth } from '../lib/withAuth';
import { MySecretComponent } from '../components/views';
const MySecretPage = props => {
const { user } = props;
return <MySecretComponent user={user} />;
};
export async function getServerSideProps(context) {
const auth = await withAuth(context);
const user = JSON.parse(JSON.stringify(auth)); // Next.js throws a validation error with the object response if I dont do this.
return {
props: {
user: user || null,
},
};
}
export default MySecretPage;
It works fine, but when the user wants to signOut, like this:
import React from 'react';
import { useRouter } from 'next/router';
import { Auth } from 'aws-amplify';
const MyComponent => () => {
const router = useRouter();
const signOut = () => {
Auth.signOut().then(() => {
router.reload();
});
};
return <button onClick={signOut}>logout</button>
}
Amplify still detects I’m logged in… Even when the user already executed the signOut function… And here’s when the project starts to act weird, the method withAuth
throws the user to /signin
even when is “logged in” but I can still navigate to any private page with the <Link />
component. I already tried removing the cache from the browser and tried with an incognito page, but nothing…
One thing to mention is that I have a header component, to show the user photo and other info, I get this info using Auth in client-side using an useEffect
. I don’t know if using Auth in the header component and also in SSR affects something…
Expected behavior Work fine, when the user wants to signout
- Device: Windows, Linux, and Android phone
- Browser Google Chrome latest version
- Version of aws-amplify: 3.3.7
- Next.js version: 10.0.1
Issue Analytics
- State:
- Created 3 years ago
- Reactions:8
- Comments:20 (8 by maintainers)
Top GitHub Comments
Closing, as https://github.com/aws-amplify/amplify-js/pull/7718 (via
v1.0.1
) should resolve this duplication issue.To install the latest version of
@aws-amplify/ui-react
, for example:Be sure to install
aws-amplify
, rather than@aws-amplify/core
directly. (aws-amplify
will install@aws-amplify/core
and other dependencies itself)Let us know if you experience any issues! 🙏
Ahhh! The SSO redirect part to
/signinreturn
is what’s interesting: https://github.com/dbhagen/next.js-authentication-aws/commit/3ec7225c614b580c85b30cdf8be0a0024b1bb020The way SSR Auth works at the moment is the
Auth
client handles the credentials negotiation, then sets credentials in cookies for the server to read.If you were to redirect back to
/
or whichever page usesAuth
orAmplifyAuthenticator
, the client-side finish the SSO flow & show the signed-in version of the app.Alternatively, you can convert
signinpage
to callAuth.currentAuthenticatedUser()
and redirect on the client to your protected page (e.g./profile
), or error. Like:I know it’s not the flow you were expecting (client negotiation vs. server), but let me know if that works. Or let me know if I’m misunderstood entirely. I haven’t had a chance to run the repository yet, but I do have a SSO version working: the difference is that it redirects back to the client to finish the login flow.