-
-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to add refresh tokens to this? #62
Comments
So I've got most of it sorted, it's just this section that's giving me grief:
If the token is expired then I have a refreshTokens function that provides a new auth token and refresh token (after checking that the refresh token is valid). The issue is, how do I push these new tokens to the client? I know it needs to go in the commented section but I have no idea what to put here... |
I've got it working. I'll close the issue but here's the solution for anyone else trying to do this:
|
Actually ignore my last comment. res.set isn't working. It just keeps using the same refresh token in the client to create a new auth token, but it doesn't send the new tokens back to the client. |
Hello @StupidSexyJake No newbie question at all! I have put your Issue into our Slack Community. Hopefully there are people who have implemented this who can help out. If you got any further with this issue, would love to see your implementation. I guess lots of other people would find it helpful 🚀 👍 |
I managed to get it working, although I'm using Next.js and cookies to store the data rather than local storage (since you can't access local storage on the server side). Refreshing tokens is handled on the client side though so you could still use local storage if that's your preference. Here's some of the changes I made: Server Side index.js : Rather than return an Authentication Error in the getMe() method, if verification fails it simply returns null as 'me' in context. Otherwise a looping issue occurs when attempting to refresh the access token, as the flow becomes:
Code example:
schema/users.js : Add a refreshAccessToken mutation and add refreshToken to Token type
resolvers/users.js: Throw the authentication error in the 'me' query so it only throws the error when the client requests 'me', create the refreshAccessToken resolver and method, and update the createToken function to include a refreshToken. I've also included a 'Remember me for 30 days' options in my sign-in form that extends the expiry of the refresh token for 30 days. Otherwise the refresh token expires after 1 hour of inactivity.
Minor changes will also need to be made to resolvers/authorization.js however I haven't had a chance to do it yet. I'll update this post when I get around to it. Client Side I'm using nookies to set and destroy cookies as it works well with Next.js. Also since I'm using Next.js my code is a little bit different. api/init-apollo.js: change the error link so that it refreshes tokens if the access token fails and a refresh token is available:
pages/login.js : Save the tokens returned from the sign-in query to cookies
And that's just about it. You might need to tweak a few things but that should be enough to get you going. If you have any questions just ask. |
Thank you letting us know about your changes @StupidSexyJake I think this will be helpful for others! |
@StupidSexyJake Thanks for sharing your code! The
I have changed that to be: const createTokens = async (user, secret, remember) => {
...
const tokens = await Promise.all([
createAccessToken,
createRefreshToken,
]);
return {
token: tokens[0],
refreshToken: tokens[1],
};
} The signIn function will now look like this: signIn: async (
parent,
{ login, password, remember },
{ models, secret }
) => {
const user = await models.User.findByLogin(login);
if (!user) {
throw new UserInputError(
'No user found with this login credentials.'
);
}
const isValid = await user.validatePassword(password);
if (!isValid) {
throw new AuthenticationError('Invalid password.');
}
const tokens = await createTokens(user, secret, remember);
return {
token: tokens.token,
refreshToken: tokens.refreshToken,
user,
};
}, @StupidSexyJake, please share with us what you other changes you have made to the |
Hi, sorry for the newbie question but how do I incorporate refresh tokens with this?
When following the boilerplate, any signed-in users will need to login again every 30 minutes due to the token expiring. From what I've read (I'm very new to backend stuff), the best way to handle this is by using refresh tokens. I've tried following a few guides online but they use a different stack so it's hard to figure out how to incorporate it into this boilerplate.
Any tips?
The text was updated successfully, but these errors were encountered: