I'm trying to integrate one App built with Next.js and Salesforce Marketing Cloud. This integration use an OAuth. After the user had logged in, he is redirected back to the Next.js App with the authorization code, then a request is sent (with the code) requiring an access and refresh token.
What is the best or correct (or secure) way to store the access and refresh token?
Can it be stored in the client? Or Should be stored in the ServerSide (in Next.js), creating a session with an HttpOnly cookie?
HttpOnly cookie storage with CSRF tokens is the best way to store jwt tokens.
Related
I used to have a custom implementation of authentication on my website. I use NestJs as backend, when I login, the backend response with access token, set the refresh token as http only cookie restricted on the refresh path and once the access Token has expires it will refresh the access token. Now that I use NextAuth, Nest can't set the cookie anymore. I was wondering what is the best practice for the refresh token ? Should I transfer the cookie to the front ?
Doesn't bother me to change the logic and backend, just want the most secure and best practice.
Now that I use NextAuth, Nest can't set the cookie anymore
Nest will send the cookie to the browser. and since you are using next you will at some point send Requests from inside getStaticProps or getServerSidePros but those functions are running on the server so they do not have any relation with the browser therefore they will not send back the cookie.
what I sugesst is to also send your refreshToken in the response and store both in next-auth session so you can access them from wherever you want inside your next app using useSession()
Doesn't bother me to change the logic
not a lot
just want the most secure and best practice
storing JWT tokens securely in the browser is impossible. see here
I completely don't understand the next-auth documentation.
I understand you can use both JWT and sessions, but how do you tell next-auth which one you're using?
And where does next-auth store its sessions or JWTs? On the server or client-side?
NextAuth.js uses a JWT to save the user's session by default, when a database adapter is not used.
NextAuth.js by default uses JSON Web Tokens for saving the user's
session. However, if you use a database adapter, the database will be
used to persist the user's session. You can force the usage of JWT
when using a database through the configuration options. Since v4 all
our JWT tokens are now encrypted by default with A256GCM.
The JWT is stored in an httpOnly cookie, not accessible on the client-side.
You can use JWT to securely store information you do not mind the
client knowing even without encryption, as the JWT is stored in a
server-readable-only cookie so data in the JWT is not accessible to
third party JavaScript running on your site.
This is documented in NextAuth.js JSON Web Tokens FAQ section.
I am trying to get my own authentication service working with my nextJS app. My own authentication service is a simple rest api that returns a JWT access token and a JWT refresh token on entering correct credentials.
Currently I am setting the JWT refresh token as a httpOnly cookie and the JWT access token into a state variable (in memory) in my nextjs app.
I am stuck at these points:
How do I pre-render sites in nextjs (getServerSideProps) with some custom user data that I want to fetch based on the JWT access token?
How can I pass this access token to getServerSideProps?
I wanted to pass the access token that is stored in memory to getServerSideProps but unfortunately I could not get it to work. Or at least I don't know how.
Do I have to put the JWT access token as a httpOnly cookie as well? Then I can retrieve the access token cookie in getServerSideProps.
But then this approach is vulnerable to CSRF as pointed out in this question:
Where to store the refresh token on the Client?
Is there a possibility to make a solution with two httpOnly cookies (one for refresh and one for access token) secure?
Is it secure to set both cookies as httpOnly and samesite strict? and set the path of the refresh token cookie to /refresh-token only? So the refresh token cookie is only sent to /refresh-token and not everywhere else.
I have seen that there is the next-auth module there I can use the getSession function on serverside but since I have my own authentication service that handles all the token management I am not sure if it is a good idea or even possible to wire my own authentication system with next-auth.
Depending on how your own authentication system works, if it adhere's to the oauth / openid-connect standards, you can simply use a custom oauth provider in next-auth.
Otherwise you could use their Credentials Provider which allows for even more customization.
I have found many links but I didn't get the solution for my problem.
I am trying to implement the jwt refresh token in asp.net core.
For storing the refresh token, I have created the table.
Based on the jwt suggestion, for SPA application, we should not expose refresh token to the client. https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
So I have planned like,
On user login, create the access token and share to the client
Create a refresh token for the access token and store it in the database and store it in HTTP only cookie
When user access to the authorized controller and action, If access token expire, I want to generate new token based on refresh token.
But,
In many places, I have found like, user will send a request. If it is unauthorised, then user will request for the new access token with the stored refresh token (local storage or something else) and again call to the valid api request.
I don't want to that as mentioned in the last paragraph(is that right one?).
When user send a request, if it is invalid, I want to validate the token in the server side itself and need to provide new access token and proceed with the last api call.
Is there any solution for this implementation like interpreting the authorize and validate?
In my opinion , it is dangerous to use/keep refresh token in SPA apps. Refresh token is powerful instrument , which is almost as powerful as the password itself . Store it in cookies or localStorage and both of these options are inherently insecure as they’re vulnerable to CSRF or XSS attacks against the client application . So i think it's better to just keep access token and do silent sign-in to renew it when access token expires.
So i don't think it's a good idea to return and use refresh token if client app is SPA application even using Code + PKCE .
I am using the JWT middleware + ASP.NET Identity to establish a simple User/Password login in my ASP.NET Core WebAPI project.
The tokens will be valid for 15 minutes. I think I will be utilizing the Refresh Token concept to keep the user logged in, when he is still browsing the site (SPA) or using the mobile app (What about a remember me option? I would create a token that's valid for a month maybe?)
So, is there any way to revoke a generated token? I am think about checking (on each request) if the user still has the right to access the API. Maybe there is another way to handle these cases?
I see a AspNetUserTokens table. Maybe there is a way to store the JWT in there automatically?! At the moment I am using ASP.NET Identity just for user authentication.
You can refer to this article : http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/
Once the user obtains long lived access token he’ll be able to access the server resources as long as his access token is not expired, there is no standard way to revoke access tokens unless the Authorization Server implements custom logic which forces you to store generated access token in database and do database checks with each request. But with refresh tokens, a system admin can revoke access by simply deleting the refresh token identifier from the database so once the system requests new access token using the deleted refresh token, the Authorization Server will reject this request because the refresh token is no longer available (we’ll come into this with more details).
The simple way is to issue short lived access tokens ,if you want to revoke the user , revoke the refresh token as the article shows , clear refresh token and access token on client side . Of cause , access token is still active until it expires .
Another way is to use Identity Server 4 Reference Tokens :
http://docs.identityserver.io/en/release/topics/reference_tokens.html
IdentityServer will store the contents of the token in a data store and will only issue a unique identifier for this token back to the client. The API receiving this reference must then open a back-channel communication to IdentityServer to validate the token