How to created a Refresh token

Am trying to have token rotation system where users can use a refresh token so they can request for a new access token…

How can I create a refresh token in Strapi v4?

2 Likes

I found only this repo https://github.com/olyphotographer/strapi-refresh-tokens
But 0 stars is adjusted…

I created a refresh token use the under code. and the resource: strapi-study-cases/strapi-server.js at main · GavinXue/strapi-study-cases · GitHub

// ref doc: https://docs.strapi.io/developer-docs/latest/development/plugins-extension.html#extending-a-plugin-s-interface
module.exports = (plugin) => {
	plugin.controllers.auth.refreshToken = async (ctx) => {
		// refresh userself token
		const newJwt = strapi.plugins['users-permissions'].services.jwt.issue({
			id: ctx.state.user.id
		})
		return { jwt: newJwt }

		// comment out next lines, and refresh the request body's token like {token: 'xxx'}
		// const { token } = ctx.request.body
		// const payload = strapi.plugins['users-permissions'].services.jwt.verify(token)
		// const newJwt = strapi.plugins['users-permissions'].services.jwt.issue({
		// 	id: payload.id
		// })
		// return {jwt: newJwt}
	}

	plugin.routes['content-api'].routes.push({
		method: 'POST',
		path: '/auth/refreshToken',
		handler: 'auth.refreshToken',
		config: {
			prefix: ''
		}
	});

	return plugin
}
1 Like

@GavinXue Thank you! I tried implementing your code above but I keep getting a Forbidden error. Any thoughts on why that could be?

maybe you did not allow the request auth in api management. you can read the docs: Configure End-users Roles - Strapi User Guide ; you will find a there is a new api.

if you still have problem, you can watch a old video of strapi v3, maybe it can help:

1 Like

@kaarbez Forbidden is the auth problem, It is nothing to do with the code I think. hope the last reply can help. and also if you need graphql refreshToken API, you can read here: GitHub - GavinXue/strapi-study-cases: strapi use cases when study, maybe it can help someone else.

1 Like

Amazing! Thank you, got it working!

@GavinXue assume you would be calling this API just before it expires? Or would you have this with public access and just refresh it once you get a forbidden error from an API?

@kaarbez The logics of when refresh the token has implemented in frontend。I will refresh code when token near expires time. I think refreshing token can not solve the forbidden problem, because the new token may be forbidden too.
note: the posted code is just a case when I study to use strapi (im a novice), we can extend this code format to build any customize api you want.

@GavinXue Thanks for the clarification.

For now, I actually incorporated verifying the token, and then automatically refreshing the token if it is expired. Here is what I have.

plugin.controllers.auth.refreshToken = async (ctx) => {
		const payload = await strapi.plugins['users-permissions'].services.jwt.verify(ctx.request.body.token)
		.catch(error => { 
			console.log(error.message)
			return {jwt: strapi.plugins['users-permissions'].services.jwt.issue({
				id: ctx.request.body.id
			})}
		});

		console.log(payload)
		return {jwt: payload.jwt}
	}

I want to update it in the future so that my front end is verifying the expiry time and only calling when close to expiry. I also found this awesome project that incorporates Apollo client : React-GraphQL-JWT-Authentication-Example

@kaarbez Thanks for your recommended repo(it’s useful for me to study). My frontend will not refresh token when expired(it will redirect to login). due to spa I will just refresh token when first request of a day(and token should be not expired.)
Hope you solve problem.

1 Like

I’m a little confused with this JWT auth system. I’ve tried the code above, and it’s working. That is, I’m getting a new jwt after reaching BASE_URL/auth/refreshToken with a header set to { Authorzation: Bearer myOldToken }. However, if just one one of those myOldToken falls into the wrong hands, then he would get indefinite access by accessing the refresh endpoint. How do I prevent this indefinite access?