-
Notifications
You must be signed in to change notification settings - Fork 37
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
Preview token is exposed to the frontend bundle #571
Comments
Hi @dsdevries, thanks for your request. The preview token shouldn't be used in a production environment. It's meant to be used only while developing or testing, in controlled staging/QA environments. When you create an API token on Storyblok you can pick between "preview" and "public". You should use a public token in production, as it only has access to the published content. cc @arorachakit |
hi @fgiuliani, They both describe that you should use the preview token. And when you do, the visual editor works out of the box. If I replace the preview token with the public token, and change the version to published by hardcoding, the code builds properly, but the visual editor doesn't work because it won't automatically loads the unpublished version in the preview iframe. When I just change the token to the public token but leave the mode to draft I get 401 and the build fails. How can I get the visual editor to work in production without exposing the preview token? |
Hey @dsdevries! I will just give a descriptive reply here so that you can take a look at different scenarios and how to proceed forward. First, let me tell you how the token logic works generally in regard to different data and editing. Then we will take a look at Next.js case. The working of the Visual Editor (live edits) in your case depends on two cases, but since we are talking about the token let me share something which will show you what is different with the draft token - The draft content contains a specific Coming onto the part where in guides we mention using the preview token - that is because write these guides where the user starts from scratch and should have access to all the content along with live editing mode. The tokens are defined in such a way that the preview token should be used inside the visual editor, which gives access to draft content and allows live editing. And on the production environment, the one that is accessible to the world - you should use public token so that the users can only access published content. This is the same thing that @fgiuliani mentioned. We never recommend using the preview token on your publicly available website. Now coming to the framework-specific part, I would like to mention that things change depending on the frameworks you choose or work with. Generally speaking, the way we have our tokens can help you anywhere. Let's say you work with a SPA like React. In that case everything is on the client side, and there is no way to hide the token as you are making a call from the frontend to the Storyblok's API. In this case, you would have two different deployments in an ideal case, one with the preview token and the other with the public token. The deployment with preview token and draft content to be used inside Visual Editor and the one with public token and published content for public users. I see that you're using Next.js, it is a framework that allows you to work on the server side as well. Before moving to the way you can make it work here, I would also like to mention that live editing depends on the way you build your website. If you're building it statically, then even when you use the preview token it can be tricky to live edit. This is the other reason why you might not be able to live edit. When you deploy your website, and use that URL, for Next.js you need to use the preview mode, it is legacy now but here is an example assuming you're using Next.js 12 - https://github.com/storyblok/react-next-boilerplate/tree/main/pages/api. If you're using Next.js 13 and building your website statically, you will need to use the new Draft Mode that they introduced. Now coming to the point where you can even use the preview token, and keep everything on the server side with Next.js. The examples you mentioned are initializing with the storyblokInit function inside the _app.js file. If you store the access token inside the env file without exposing it on the browser (i.e. without adding NEXT_PUBLIC) to it, you will see that it will still fetch the data and enable the live editing. As getStaticProps and getStaticPaths run only on the server, you won't face any errors using this way. This is just to confirm that it can work exactly the way you would want. The variable is on the server side completely and won't expose it to the browser. Just adding the docs for env in case you want to take a look - https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables But again, I'd like to highlight that these things depend on the frameworks. And in this case too, I would recommend having two different deployments. One with the public token for users to access, that only has published data. And another one that has the preview token and draft content with enabled preview/draft mode to be used inside the editor. Also, just wanted to give an example in the last - let's say you fetch something on the client side here, you will face an error because the storyblokApi won't get the token on the client. Here is an example of fetching something on the client - https://github.com/storyblok/next.js-ultimate-tutorial/blob/master/components/AllArticles.js. Here we are fetching all articles on the client. To make this work, the token has to be on the client. So you can put it hard coded or maybe add NEXT_PUBLIC to it. Just wanted to mention that this is also one of the reasons that we are using the token on the client and haven't described this approach in the tutorial. I hope this helps, let me know your thoughts on this. |
Hey @dsdevries did the message from @arorachakit help you? |
hi @fgiuliani and @arorachakit, It is just that this isn't clear from the documentation. From reading the documentation, I was under the assumption, that it is safe to use the preview token. And because the the Storyblok-react library is basically a singleton, I also assumed that it was only used server side by nextjs. I would suggest updating the documentation to advise the two separate deployments. Also, I would stress that, as our client will be using the cms, the preview/staging deployment is also considered production. We basically have 3 separate environments (development, acceptance, production) connected to 3 different spaces in storyblok. Each environment has a preview deployment and a public deployment. When we develop a new feature, we develop against the development environment and we also test whether preview mode is working. When development is ready, we deploy it to acceptance where the PO is testing. She will also test preview mode. Then when the feature is acceptance, it is deployed to production where the content editors will work in preview mode. Thus, preview mode is not a pre-production mode. It would however be nice if the two separate deployment would not be necessary. After all, when you are logged, you already have a session. It would be very easy to just build in a mechanism in the library that takes the token from your session when you are in preview mode, and takes the public token when you are not logged in. This will take away a lot of confusion. |
Hey @dsdevries ! Thank you so much for your feedback regarding the documentation, we are in the process of improving this part. I am sure it will be useful for many people. Regarding the changes in the sdk, I understand what you're trying to say. It definitely sounds interesting. But I really like the overall concept and idea, if we are able to implement it in such a way where we give the flexibility for users to choose this and keep the things they want - it would be great and maybe we can even think it for more SDKs. |
Describe the issue you're facing
When I follow the standard implementation guides for nextjs, I am suppose to pass the preview token to the client side to initiate the api client. This is done to enable live editing and preview mode with zero effort, but it introduces a major security hole.
Once you retrieved the preview token, you are able to fetch all unpublished content using the api. This is a serious concern for clients that have unpublished content of which is vital to remain secret until it is published. Think of financial result of listed companies, product launches or other strategic content.
Please update the library to either use the preview token or user credentials passed by the cms editor and use server side validation for this. Or update the manuals to create a custom api route as a proxy.
Reproduction
https://reinvent-daalse-singel-rebuild.vercel.app
Steps to reproduce
search for the preview token in the _app-[hash].js file
System Info
Used Package Manager
npm
Error logs (Optional)
No response
Validations
The text was updated successfully, but these errors were encountered: