<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jonatan</title>
    <description>The latest articles on DEV Community by Jonatan (@jonatanvm).</description>
    <link>https://dev.to/jonatanvm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717926%2Fe6682d8e-6f71-4a5f-986b-3c304da1eb5f.png</url>
      <title>DEV Community: Jonatan</title>
      <link>https://dev.to/jonatanvm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonatanvm"/>
    <language>en</language>
    <item>
      <title>How to store user data client side</title>
      <dc:creator>Jonatan</dc:creator>
      <pubDate>Sun, 28 May 2023 11:41:57 +0000</pubDate>
      <link>https://dev.to/jonatanvm/user-data-in-your-web-app-best-practices-for-storage-and-security-2l88</link>
      <guid>https://dev.to/jonatanvm/user-data-in-your-web-app-best-practices-for-storage-and-security-2l88</guid>
      <description>&lt;p&gt;Modern web applications often store and display user data in the browser to personalize the user experience. This might include non-sensitive data, such as user preferences or UI state, and sensitive data, like usernames or email addresses. Data can be stored in various ways, including in cookies, LocalStorage, SessionStorage, or IndexedDB. However, storing sensitive data in the browser will open your application to security risks, such as Cross-Site Scripting (XSS) attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross-Site Scripting (XSS) TL;DR
&lt;/h3&gt;

&lt;p&gt;Cross-Site Scripting (XSS) is a web security vulnerability that allows attackers to inject malicious scripts into web pages, exploiting unvalidated or improperly escaped user input. These scripts can steal sensitive information or perform actions on behalf of the user, posing serious security risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you should do TL;DR
&lt;/h2&gt;

&lt;p&gt;The more persistent your user information storage is the more susceptible to XSS attacks your application is. Therefore, the most secure approach is to refrain from storing any sensitive user information in the client-side. However, if user data storage is inevitable, the most secure approach is to fetch it on-demand, using it only when necessary, and avoiding persisting this information across pages. This practice significantly mitigates potential risks, ensuring a safer user experience and a more secure application.&lt;/p&gt;

&lt;p&gt;If you absolutely have to store user information in the browser here are a few options organized by more susceptible to XSS and less susceptible to XSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Less XSS vulnerable options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fetch user information when needed
&lt;/h3&gt;

&lt;p&gt;Once the user logs in, you can make an API request to fetch the user's profile information, including their email.&lt;br&gt;
You will need to re-fetch this information when the user reloads the page. But if you only request the information when needed, malicious scripts have a smaller attack vector.&lt;br&gt;
If you store this information in the application's state your attack vector increases, but will be smaller than in the more persistent storage options explained below.&lt;/p&gt;

&lt;h2&gt;
  
  
  More XSS vulnerable options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Store the email in a non-HTTP-only secure cookie
&lt;/h3&gt;

&lt;p&gt;You can store the email in a cookie that isn't set to HTTP-only. This would make it accessible to JavaScript through the document.cookie API. Cookies also persist across page refreshes. But, like LocalStorage, cookies are also vulnerable to XSS attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use the Session or Local Storage
&lt;/h3&gt;

&lt;p&gt;On successful login, you can store the user's email in the Session Storage or Local Storage. The email can then be retrieved and displayed whenever necessary. However, as discussed in previous responses, this approach has some security risks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Embed the email in the token (JWT)
&lt;/h3&gt;

&lt;p&gt;You can include the email in the payload of the JSON Web Token (JWT) that is sent to the client after a successful login. The frontend can decode the token and extract the email to display it. However, be aware that the information in a JWT is not encrypted, only encoded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Embed in the page HTML
&lt;/h3&gt;

&lt;p&gt;When the server generates the HTML for the page, it can embed the user's email directly into the script. This can be a good option if your server renders your pages, but it won't work if your frontend is a single-page application that doesn't regularly receive full page updates from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In conclusion&lt;/strong&gt;, no matter how you go about it storing user data on the client side will open up your application to security risks, such as XSS attacks. The principle of reducing attack vectors guides us towards best practices: it's safest not to store any sensitive user information client-side if possible. If storage of user data is essential, minimizing persistence and fetching data on-demand is the recommended approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember to ensure you're complying with all relevant privacy laws and regulations when handling user data.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>database</category>
    </item>
    <item>
      <title>How to deploy a Django App on Heroku in less than 5 minutes</title>
      <dc:creator>Jonatan</dc:creator>
      <pubDate>Sat, 02 Oct 2021 19:05:42 +0000</pubDate>
      <link>https://dev.to/jonatanvm/how-to-deploy-a-django-app-on-heroku-in-less-than-5-minutes-4m7n</link>
      <guid>https://dev.to/jonatanvm/how-to-deploy-a-django-app-on-heroku-in-less-than-5-minutes-4m7n</guid>
      <description>&lt;p&gt;In this short tutorial, I will demonstrate how to deploy a Django project on Heroku while serving static files from your own domain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;python (&lt;a href="https://www.python.org/downloads/"&gt;https://www.python.org/downloads/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Django (&lt;a href="https://docs.djangoproject.com/en/3.2/topics/install/"&gt;https://docs.djangoproject.com/en/3.2/topics/install/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;virtualenv (&lt;a href="https://virtualenv.pypa.io/en/latest/installation.html"&gt;https://virtualenv.pypa.io/en/latest/installation.html&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;pip (&lt;a href="https://pip.pypa.io/en/stable/installation/"&gt;https://pip.pypa.io/en/stable/installation/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;heroku-cli (&lt;a href="https://devcenter.heroku.com/articles/heroku-cli"&gt;https://devcenter.heroku.com/articles/heroku-cli&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need to use virtualenv, but it is highly recommended to use an isolated environment for different projects. Another option to virtualenv, for deploying to Heroku, is pipenv.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Django, virtualenv, pip and the heroku-cli on Ubuntu
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install python3
sudo apt install python3-django
sudo apt install python3-virtualenv
sudo apt install python3-pip
sudo snap install --classic heroku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Django project
&lt;/h2&gt;

&lt;p&gt;We can now create our Django project named myproject&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django-admin startproject myproject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up your virtual environment
&lt;/h2&gt;

&lt;p&gt;You now want to go to the root of your project and set up your virtual environment.  &lt;/p&gt;

&lt;p&gt;Navigate to your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd myproject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a virtual environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;virtualenv venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Activate your virtual environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Django in your virtual environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install django
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a new Heroku project
&lt;/h2&gt;

&lt;p&gt;We now want to create a new Heroku project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a domain at &lt;a href="https://example.herokuapp.com"&gt;https://example.herokuapp.com&lt;/a&gt; so select the project name to be the domain you want your project to be hosted at. (You can later add a custom domain).&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing the secret key
&lt;/h2&gt;

&lt;p&gt;First, we want to change the &lt;code&gt;SECRET_KEY&lt;/code&gt; to an environment variable, because we want to have a unique &lt;code&gt;SECRET_KEY&lt;/code&gt; in production that we don't push to version control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SECRET_KEY = os.getenv('SECRET_KEY', 'change-in-production')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can set our production environment variable with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku config:set SECRET_KEY=very-long-secret-key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now need to set up static files and turn off DEBUG mode in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up static files
&lt;/h2&gt;

&lt;p&gt;We are going to use whitenoise to serve static files. First, we need to install it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install whitenoise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we add the &lt;strong&gt;whitenoise&lt;/strong&gt; middleware to the top of the middleware section&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MIDDLEWARE = [
    'whitenoise.middleware.WhiteNoiseMiddleware', # First in list
    ...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we set up the path of our static files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then install &lt;strong&gt;django_heroku&lt;/strong&gt; to configure default values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install django_heroku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We enable the &lt;strong&gt;django_heroku&lt;/strong&gt; settings, but set &lt;strong&gt;staticfiles&lt;/strong&gt; and &lt;strong&gt;allowed_hosts&lt;/strong&gt; to False, because we want to specify our own static file options and change &lt;strong&gt;allowed_hosts&lt;/strong&gt; from the &lt;strong&gt;django_heroku&lt;/strong&gt; default value ['*'] to prevent Host Header attacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django_heroku.settings(locals(), staticfiles=False, allowed_hosts=False)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the bottom of the &lt;strong&gt;settings.py&lt;/strong&gt; file, we will now add settings specific to Heroku.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if "DYNO" in os.environ:
    STATIC_ROOT = 'static'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Initializing git
&lt;/h2&gt;

&lt;p&gt;We will now add git to our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding Heroku to your git remotes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku git:remote -a example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Disabling DEBUG and settings allowed hosts
&lt;/h2&gt;

&lt;p&gt;We now want to disable DEBUG in production and add our domain to our allowed hosts. We add these options in the if &lt;code&gt;"DYNO" in os.environ&lt;/code&gt; block because we only want these settings to be in effect in production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if "DYNO" in os.environ:
    STATIC_ROOT = 'static'
    ALLOWED_HOSTS = ['example.herokuapp.com']
    DEBUG = False
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding the Procfile
&lt;/h2&gt;

&lt;p&gt;First, we will add the Procfile. To do this just add a file called Procfile (without any extension) to the root of your project. On ubuntu and mac simply write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch Procfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then install gunicorn which is the HTTP server we use in production on Heroku.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install gunicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while in the terminal while in the root directory. Next, add the following to the file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: gunicorn myproject.wsgi --log-file -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding the requirements.txt file
&lt;/h2&gt;

&lt;p&gt;Our last step is to create the requirements.txt file, which will specify all the packages that we have used. Since we used a virtual environment, this step is very easy. All we have to do is type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the terminal while being in our projects root directory. This will add all our packages installed through pip to the requirements.txt file automatically.&lt;/p&gt;

&lt;p&gt;If you weren't using a virtual environment, you can also manually create a requirements.txt file in the root directory and manually add all the requirements. If you did everything correctly your requirements.txt file should look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;asgiref==3.4.1
dj-database-url==0.5.0
Django==3.2.7
django-heroku==0.3.1
gunicorn==20.1.0
psycopg2==2.9.1
pytz==2021.1
sqlparse==0.4.2
whitenoise==5.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploying to Heroku
&lt;/h2&gt;

&lt;p&gt;We are now ready to deploy our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "My first project is ready to be deplayed"
git push heroku main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we are done! Your project is now deployed to Heroku.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional settings for production
&lt;/h2&gt;

&lt;p&gt;If you want to make sure your project only works over https you want to add the following options to your production settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if "DYNO" in os.environ:
    STATIC_ROOT = 'static'
    ALLOWED_HOSTS = ['example.herokuapp.com']
    DEBUG = False
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
    SECURE_SSL_REDIRECT = True
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CSRF_COOKIE_SECURE &lt;/code&gt; -  Ensures your CSRF cookies will be served over https.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SESSION_COOKIE_SECURE&lt;/code&gt;  -  Ensures your session cookies will be served over https.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SECURE_PROXY_SSL_HEADER&lt;/code&gt; &amp;amp; &lt;code&gt;SECURE_SSL_REDIRECT&lt;/code&gt;  -  Will redirect all HTTP traffic to https&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Additional reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devcenter.heroku.com/articles/creating-apps"&gt;Creating Apps from the CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devcenter.heroku.com/articles/config-vars"&gt;Configuring config variables in Heroku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devcenter.heroku.com/articles/django-assets"&gt;Django and Static Assets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devcenter.heroku.com/articles/python-gunicorn"&gt;Deploying Python Applications with Gunicorn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devcenter.heroku.com/articles/django-app-configuration"&gt;Configuring Django Apps for Heroku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/"&gt;Django official deployment checklist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>django</category>
      <category>heroku</category>
      <category>postgres</category>
    </item>
  </channel>
</rss>
