<?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: Diego Uribe Gamez</title>
    <description>The latest articles on DEV Community by Diego Uribe Gamez (@diegoug).</description>
    <link>https://dev.to/diegoug</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%2F15564%2F8fd2e641-6b3c-4368-b812-44847921fbd3.jpg</url>
      <title>DEV Community: Diego Uribe Gamez</title>
      <link>https://dev.to/diegoug</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diegoug"/>
    <language>en</language>
    <item>
      <title>Django REST framework +OAuth</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Wed, 17 Nov 2021 12:40:10 +0000</pubDate>
      <link>https://dev.to/diegoug/django-rest-framework-oauth-pld</link>
      <guid>https://dev.to/diegoug/django-rest-framework-oauth-pld</guid>
      <description>&lt;p&gt;In this article we are going to configure Django, this excellent framework for web development, in addition to this we are going to integrate a module called Django rest framework which is a toolkit that will allow us to create REST views in a simple way, and we will also protect the application using OAuth, this is an open protocol to manage security and is especially useful for applications that want to access our system externally.&lt;/p&gt;

&lt;p&gt;Let's do it&lt;/p&gt;

&lt;p&gt;In this example we are going to follow the following route:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting up the development environment&lt;/li&gt;
&lt;li&gt;Data model&lt;/li&gt;
&lt;li&gt;Create a request list&lt;/li&gt;
&lt;li&gt;Configuring OAuth&lt;/li&gt;
&lt;li&gt;Protect views&lt;/li&gt;
&lt;li&gt;Automate OAuth&lt;/li&gt;
&lt;li&gt;Final notes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Repository url:&lt;br&gt;
&lt;a href="https://github.com/diegoug/Django-REST-framework-OAuth" rel="noopener noreferrer"&gt;https://github.com/diegoug/Django-REST-framework-OAuth&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up the development environment
&lt;/h3&gt;

&lt;p&gt;In Windows and in Visual Studio Code (vscosde) the cygwin terminal was configured, which has a behavior similar to unix systems, and additionally, the make and bash-completion programs were installed, this will be useful as a standard to be able to run our project on linux and mac which are unix systems.&lt;/p&gt;

&lt;p&gt;We are going to add our configuration of the directory .ssh in the root of (C:), which is where our terminal will look for the ssh keys through our command (cd C:), this takes us to the path "/cygdrive/c/" which is access to disk C from cygwin, this configuration will help us to keep the django service running, also to be able to access from terminal and to be able to activate Django's debugging mode in vscode&lt;/p&gt;

&lt;p&gt;Having docker and compose installed, we are going to position in the directory of the project that we cloned, we create the docker network, we compile the project and we are going to run the containers with the following Makefile commands&lt;/p&gt;

&lt;p&gt;´´´&lt;br&gt;
$ make create-network&lt;br&gt;
$ make build-development&lt;br&gt;
$ make start-development&lt;br&gt;
´´´&lt;/p&gt;

&lt;p&gt;After starting a clean environment in Docker, the project named django_rest_framework_MS was created inside&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8okqvp6vcmbi14wbb59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8okqvp6vcmbi14wbb59.png" alt="Project folder inside"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We configure the database that we are going to use, for our case it will be PostgreSQL that has excellent functionalities that adapt well to the functionalities of the django ORM, migrate, create a super user in the terminal and with this we have access to the admin of django&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9lag8pdl2ns2ajeyspa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9lag8pdl2ns2ajeyspa.png" alt="Database configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6j0cvu34qmjfsfhomy7k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6j0cvu34qmjfsfhomy7k.png" alt="Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxar2hqgcx1xuakllfn8l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxar2hqgcx1xuakllfn8l.png" alt="Admin login"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ymyp8xc49hqr42bzi92.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ymyp8xc49hqr42bzi92.png" alt="Admin inside"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Data model
&lt;/h3&gt;

&lt;p&gt;After creating a project, we are going to create an application for our library and then we are going to create two models, one for books and the other for authors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8btpuewvtgvb6t1owt00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8btpuewvtgvb6t1owt00.png" alt="Books and authors models"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a request list
&lt;/h1&gt;

&lt;p&gt;Once our models are created, we create a simple view that is capable of delivering a list of books and the authors of each book, in a web view as well as in a rest view.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;urls.py&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3udfvjx0ixq8jvqrw19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3udfvjx0ixq8jvqrw19.png" alt="urls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;views.py&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxnhmfviccd4dfopjeuzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxnhmfviccd4dfopjeuzo.png" alt="views"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We add some sample data and test the functionalities of the view using postman and the web browser&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Postman&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1qm63sx9yy0antke2ts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1qm63sx9yy0antke2ts.png" alt="Postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chrome&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznggkc2x1iy3om5oji7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznggkc2x1iy3om5oji7m.png" alt="Chrome"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring OAuth
&lt;/h3&gt;

&lt;p&gt;We are going to install Django OAuth Toolkit, on the official page of the library there is a section that details the installation of this library, in addition to the configuration to work with the Django Rest framework, you can find it &lt;a href="https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html#step-1-minimal-setup" rel="noopener noreferrer"&gt;HERE! in this link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installing it, we are going to perform the following configuration to obtain the OAuth credentials of the super user that we have created previously from the django admin&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzucrf0sln86efumm9g6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzucrf0sln86efumm9g6.png" alt="OAuth django admin user credentials"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We copy the credentials and use them to get our token from Postman&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5mdpa2ih2xg9jqzbrvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5mdpa2ih2xg9jqzbrvm.png" alt="Postman get token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Protect views
&lt;/h2&gt;

&lt;p&gt;We must protect the view from two sides, from the web side by username and password and then from the api side using OAuth&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web view&lt;/strong&gt;&lt;br&gt;
We globally configure Django rest framework in the settings so that the views use username and password&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7d2wte7lveggi0pxhxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7d2wte7lveggi0pxhxo.png" alt="django rest framework settings permission"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We test that it does not allow access&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqx6wc6d121bvzs1fj9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqx6wc6d121bvzs1fj9y.png" alt="Error access in web view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We add the urls of Login and Logout&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9elyoe8vxi11u0fn46q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9elyoe8vxi11u0fn46q.png" alt="login urls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We configure the redirect urls of the settings&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk54orgfcannfqcr6pnac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk54orgfcannfqcr6pnac.png" alt="settings url redirects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We test the correct access&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhg2658nh2bvu8sess2vg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhg2658nh2bvu8sess2vg.png" alt="Login form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf7phbj6zi3mu82cnlj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf7phbj6zi3mu82cnlj2.png" alt="Correct access"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works :D&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API view&lt;/strong&gt;&lt;br&gt;
As we want the same view to handle both the web part and the api, we are not going to leave the two types of permissions declared at the same time in the settings (user / password and OAuth) the default configuration will be with username and password, and for the api urls we are going to overwrite the permissions with the OAuth configuration.&lt;/p&gt;

&lt;p&gt;We tested that it does not allow access by postman to the api view&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2haaxo1f482xblzxqq2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2haaxo1f482xblzxqq2b.png" alt="Postman api error access"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We add to the books view a configuration of authentication_classes and permission_classes when the view is instantiated on the url of the api&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztmpyaa3jzzlab3mptwr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztmpyaa3jzzlab3mptwr.png" alt="Custom permission api access"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We test the correct access&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9i68fjm4jqjx04mvm18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9i68fjm4jqjx04mvm18.png" alt="Postman api correct access"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works :D&lt;/p&gt;

&lt;h2&gt;
  
  
  Automate OAuth
&lt;/h2&gt;

&lt;p&gt;To finish, we are going to create a web endpoint that once the user has accessed the web application and navigates to a specific url in the web application, it gives him the Oauth credentials, we do this so as not to manually create configurations for each user that try to access through postman, if not rather that they enter the web application and look for their credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;urls.py&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xvix454t25pmirplxne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xvix454t25pmirplxne.png" alt="urls to get token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;views.py&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjgglzjln8oga45vkp5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjgglzjln8oga45vkp5h.png" alt="view to distapch token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chrome&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k992yfibf80up4lrphu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k992yfibf80up4lrphu.png" alt="Deliver credentials in browser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works :D&lt;/p&gt;

&lt;h2&gt;
  
  
  Final notes
&lt;/h2&gt;

&lt;p&gt;It is important to note that this is only an example, and the advanced security configuration will depend on the administrator, an example is SSL encryption and the correct configuration of the settings that guarantee this security&lt;/p&gt;

&lt;p&gt;We can also apply a microservices type configuration, to place a transversal and transparent authentication layer to all Django type micro services, but this is the subject of another article, now if you are interested in getting this part faster please leave a comment and share.&lt;/p&gt;

&lt;p&gt;See you next time.&lt;/p&gt;

</description>
      <category>django</category>
      <category>oauth</category>
      <category>api</category>
      <category>djangorestframework</category>
    </item>
    <item>
      <title>L2/Junior developer at Platzi</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Tue, 10 Dec 2019 05:02:47 +0000</pubDate>
      <link>https://dev.to/diegoug/l2-junior-developer-at-platzi-1g35</link>
      <guid>https://dev.to/diegoug/l2-junior-developer-at-platzi-1g35</guid>
      <description>&lt;p&gt;Related article:&lt;br&gt;
&lt;a href="https://dev.to/diegoug/l3-junior-developer-at-alkanza-515k"&gt;L3/Middle developer at Alkanza&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a company that is dedicated to helping people create and develop innovative ideas in the world of technology, and as a consequence for these people they improve their quality of life; It is also a team of people who guide a community.&lt;/p&gt;

&lt;p&gt;This company also helped me grow from L2/Junior to L3/Medium developer, and many people participated in my personal development, each of them giving me personal and professional lessons, directly or indirectly, I could say that this was once the best growth school in which I participated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Professional lessons
&lt;/h2&gt;

&lt;p&gt;Platzi is the best example of the search for quality in the professional aspect to give students the best experience, they can even reach the professional point where they experiment with developments and technologies that they do not yet offer in their courses to validate the new technologies that they are good for the future, that makes the platzi courses one of the best sources of information and they are also a signal to know where the technology is going.&lt;/p&gt;

&lt;p&gt;And the lessons that can be learned from this are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We must see where the technology is going, whether we use it or not, this will give us the perspective of how these technologies can help us or also teach us to see what people we want to join.&lt;/li&gt;
&lt;li&gt;We must investigate and adopt the standards that represent quality and scalability, this will help us to give our best in the things we do, and these will represent us in front of others.&lt;/li&gt;
&lt;li&gt;We must lose the fear of creating and experiencing new things.&lt;/li&gt;
&lt;li&gt;Finally, these lessons and others represent Platzi's motto "Never stop learning"&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Personal lessons
&lt;/h2&gt;

&lt;p&gt;Not only do you live on technology, it is also important to grow personally, because you can always learn something new and nobody is perfect, and here having lived with a group of people who do their best to develop their professional aspect I also managed to learn personal lessons, which I understood at the time or later.&lt;/p&gt;

&lt;p&gt;You can always grow, that is why we must strive to think that it is necessary to be the best of ourselves, be people who can help others grow, realize our defects and work on it, all this so that we all grow together, and it doesn't matter if others don't realize, we should help them understand.&lt;/p&gt;

&lt;p&gt;To lose is to win, always that we strive to grow and although we fall if we learn a lesson, but we will only benefit when we manage to reflect on it, and to achieve this we must meditate in our words, the message behind people, which is behind his expressions and his language, here the most important thing could be to shut up and listen, and then be able to give a good answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does it hold for the future?
&lt;/h2&gt;

&lt;p&gt;We who are in this community can see that if we work together and strive to learn we can improve the future, but not everything is rosy since we are in a struggle, the world is increasingly complex, each time we are more, many people use what they learn from technology for bad things, there are more conflicts, many people do not know how to learn new things, many people do not know Platzi, the situation will become increasingly difficult.&lt;br&gt;
 &lt;br&gt;
Platzi helps us withstand this crisis, giving us tools, holding us so that when the greatest difficulties pass we can get ahead, and we can take advantage to take the lead, so nothing has been lost and in fact this is the best time to "never stop to learn".&lt;/p&gt;

</description>
      <category>platzi</category>
      <category>junior</category>
      <category>developer</category>
    </item>
    <item>
      <title>L3/Middle developer at Alkanza</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Thu, 05 Dec 2019 11:52:12 +0000</pubDate>
      <link>https://dev.to/diegoug/l3-junior-developer-at-alkanza-515k</link>
      <guid>https://dev.to/diegoug/l3-junior-developer-at-alkanza-515k</guid>
      <description>&lt;p&gt;Related article:&lt;br&gt;
&lt;a href="https://dev.to/diegoug/l4-senior-developer-at-mesfix-2n0g"&gt;L4/Senior developer at Mesfix&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Alkanza
&lt;/h1&gt;

&lt;p&gt;It was a fintech that specialized in managing and developing high-level investment services, with a team of professional financials and developers to make high-impact technologies.&lt;/p&gt;

&lt;p&gt;In my experience, the best thing about the company is its financial responsibility, which can reach an unpredictable detail, this because for the company the client must feel backed by the experience and the good management of their finances.&lt;/p&gt;

&lt;p&gt;On the technological side, when I was working in the company, one thing that I learned is to see how although from the beginning things could have worked badly, many things cannot be remade, but rather we have to move on and we have to implement improvements on the proposed things, so that you can walk towards the future.&lt;/p&gt;

&lt;p&gt;One of the things that came to my attention was to understand the legacy code, the current functionalities due to the complexity of the same and above all I was able to propose new ideas due to the aforementioned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Overengineering&lt;/li&gt;
&lt;li&gt;The spaghetti code&lt;/li&gt;
&lt;li&gt;Sub processes out of control&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overengineering
&lt;/h2&gt;

&lt;p&gt;From the lessons that I let myself be in the technological team was to understand how a technology can be misunderstood, due to the circumstances of the engineers, this can cause a technology to be implemented in a very complex way, reaching its purpose but taking a very long road, and in practice you could see spaghetti code, sub processes out of control, functionalities of the language without purpose or with an inappropriate purpose and duplication of code, all this leading to generate delays in the new functionalities.&lt;/p&gt;

&lt;p&gt;And how to repair this?&lt;/p&gt;

&lt;p&gt;As I told you, if you get to see engineering level failures but everything is working because the client is being served, the most logical thing is to say that nothing is failing, then what you should do is enter new functionalities with the corrections and go correcting the other features periodically.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  The spaghetti code
&lt;/h2&gt;

&lt;p&gt;After a certain point it has no solution, this happens when a practice such as fucional programming is improperly implemented, and it can happen that a function depends on many other functions, or that a parameter is passed through a parent function but being used for a granddaughter function :D then the best thing that could be done is to create new functionalities with the new practices.&lt;/p&gt;

&lt;p&gt;The correct way to implement the fucional program is for a parent function to call a daughter function, that if a daughter function needs a parameter but the parent function has the information to obtain that data then call a function that brings that parameter and then there is if you pass it to the daughter function, making the main cycle pass in the father function.&lt;/p&gt;

&lt;p&gt;In fucional program, in a parent function the following actions should happen, 1. validate input parameters and respond to the client if there is any problem to correct them, so that the children do not deal with errors or changes in the data, 2. obtain external parameters, can be database objects to perform the requested action, this step could be optional, 3. execute the action with all the data already present, 4. answer the request, this can be positive or negative, depending on the result of the Data operation, this is my vision of functional programming.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  Sub processes out of control
&lt;/h2&gt;

&lt;p&gt;Django can perform sub processes using celery, here the important thing is that a sub process is that, just one, that fulfills its function and is doing a well-done task, but it could happen that by having the ability to create sub processes we make a sub process creates another sub processes only by evaluating a condition, here the solution is simpler, it can be corrected simply by unifying the sub processes or making the new functionalities well done.&lt;/p&gt;

&lt;p&gt;Language functionalities without purpose or with an inappropriate purpose and duplication of code, that can be solved with training and a better understanding of the language, in addition to a study of good practices and standards by the development team, when it is achieved we can see how the team better develop its code, being careful not to over-engineer and giving it Higher quality to the final product.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;At Alkanza, when facing these difficulties, we were able to begin the development process aimed at creating solutions that were not only impactful but also efficient, unfortunately this company stopped working.&lt;/p&gt;

&lt;p&gt;Mauricio Gutierrez left the biggest lesson because his financial responsibility inspired me to think about the importance of managing my finances well and having a lot of attention to the detail of the finances of others, since it is for all an important aspect of our lives and deserves the greatest attention.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

</description>
      <category>development</category>
      <category>junior</category>
      <category>django</category>
      <category>celery</category>
    </item>
    <item>
      <title>L4/Senior developer at Mesfix</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Fri, 22 Nov 2019 15:17:57 +0000</pubDate>
      <link>https://dev.to/diegoug/l4-senior-developer-at-mesfix-2n0g</link>
      <guid>https://dev.to/diegoug/l4-senior-developer-at-mesfix-2n0g</guid>
      <description>&lt;p&gt;Related article:&lt;br&gt;
&lt;a href="https://dev.to/diegoug/l5-or-senior-developer-what-s-next-1jib"&gt;L5/Senior developer, what's next?&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Mesfix
&lt;/h2&gt;

&lt;p&gt;This is a company that contacts buyers with companies, these companies sell their invoices receivable to payers, sell their invoice for a quick payment losing a small percentage, the company that sells can reinvest and expedite its operation, and the buyer of the invoice use your money and earn a percentage at the time the payer pays the bill, in Colombia this is an excellent idea since companies can take between 15 and 20 days to pay for the products they already received; Mesfix is currently expanding its product range.&lt;/p&gt;

&lt;p&gt;In my experience in this company the best of the development team is its culture; Manuel his CTO makes each of its members feel as part of his Family.&lt;/p&gt;

&lt;p&gt;One of the things that impressed me most about the Mesfix team and its technology was the very intuitive and organic way in which they implemented the micro services methodology, in a simple way they managed to form the idea that a backend for frontend consults an orchestrator that may or may not be related to a micro service, this orchestrator would be responsible for unifying the information without performing logical business operations and the micro services would be responsible for operating the logical queries requested by the orchestrator and operating the information either by storing or reorganizing it, just great.&lt;/p&gt;

&lt;p&gt;When I arrived, they had already gone through a process where much of the monolithic architecture was separated by passing it to a microservice architecture, and my task was to help the team implement good development practices that were not available at the time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Index:
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- [GitFlow](#gitFlow)
- [Docker](#docker)
- [Unittest](#unittest)
- [API RestFull](#api-restfull)
- [Documentation](#documentation)
- [jenkins and continuous automation](#jenkins-and-continuous-automation)
- [Micro data service and django admin](#micro-data-service-and-django-admin)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  GitFlow
&lt;/h2&gt;

&lt;p&gt;The first thing was to organize the process of developing functionalities in the repository, we went on to implement the GitFlow methodology, with the nomenitlatures, feature / name-functionality that would be the name of the branch to create a new functionality, hotfix / fix that would be the name of the branch to fix errors in production and the master branch would be blocked from merge to pass the code integrations using only pull requets, I know that it is not all the GitFlow standard but for a team that had not worked using branches and pull request It would be an excellent start.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;
&lt;h2&gt;
  
  
  Docker
&lt;/h2&gt;

&lt;p&gt;From machine installation to installation in Docker; When I arrived at Mesfix, all the developers installed the platform on their local machine, some with Linux, others with Mac, this was quite complicated since there were varied problems when installing or performing maintenance of not knowing why in some machines it worked and in others, in addition to the same problems happening in production, it was then that the docker environment was developed for development mode, and then for production mode.&lt;/p&gt;

&lt;p&gt;From this experience, what I remember the most and the most joy was that when we had finished the development mode so that the team could work faster, at that time the company supplied a Mac to each developer and we could try it on these, here the result It was a success and we went to work more calmly and without relying directly on our machines to start the developing platform.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;
&lt;h2&gt;
  
  
  Unittest
&lt;/h2&gt;

&lt;p&gt;Unitary endpoints tests were implemented using ava.js, so that developers could use it, we match the test file architecture to the services architecture, and add a command to a Makefile so that they could run the tests in three different ways , a) run all the tests, b) run all the tests of a service, and c) run all the tests of a functionality.&lt;br&gt;
This is the organization of the test files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root-test-files
  service_1
    functionality_1.js
    functionality_2.js 
  service_2
    functionality_1.js
    functionality_2.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make start-testing
make start-testing service_1
make start-testing service_2 functionality_2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  API RestFull
&lt;/h2&gt;

&lt;p&gt;An important part of the software development that we wanted to improve was to adhere to the industry standards and stop developing instinctively, so the standard we gave priority was to the RestFull API, the general idea was to optimize the loading time and improve the search performance, for which we choose the most delayed endpoints, we study them and rethink them adhering to the standard, and this development initially optimized the performance of the commercial area and subsequently of the clients giving a great boost to the company.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;We must always look at the documentation when we do not want a system to be dependent on those who develop them, this part is always the most complicated, because there are many standards, because the documentation is not maintained, because the development is very Fast and there is no time to do it, there are many things that can happen in the process, and a problem we wanted to attack was the fact of not knowing where to leave the documentation, for this we noticed that most of our resources were rest and we were doing Resfull new versions, we decided to add the documentation to the same endpoints using a parameter to be consulted, where the first thing we evaluated was the precence of the parameter and if it happened the endpoint documentation was delivered to the client, now the documentation was in a markdown file, which the endpoint read and transformed into HTML to deliver to the client that made the request, in addition to these Markdown files could also be seen through the github interface giving it an extra point, in case a developer needs the documentation, he does not need to invoke the endpoint and instead we give him the link to the documentation.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  jenkins and continuous automation
&lt;/h2&gt;

&lt;p&gt;On this part I was not very much in front of the development but I did have the opportunity to guide a co-worker that I was learning, and this might not be a good antecedent for the result, but the guide was the key part to realize this functionality, in general several key points were worked on which could be the starting point for the future scalability of the project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pipeline: a deployment flow that might be able to identify potential problems before, during and after deployment&lt;/li&gt;
&lt;li&gt;environments: possible deployments with different goals in different areas of development, with fidback included.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  Micro data service and django admin
&lt;/h2&gt;

&lt;p&gt;The storage, centralization through databases, and administration by the area of operations is an essential part of the study of the clients, and an MVP was carried out with the goal of not having direct interaction with the design area to give it a growth fast independent of other areas, we have decided to use the Django admin since it technically had these characteristics, since when programming the django admin it reacts visually to the programming lines, and it got to be programmed in a very advanced level of python, and the project has growth potential, but from this experience I specifically have another post to which you can go  &lt;a href="https://dev.to/diegoug/what-is-the-django-admin-for-5deh"&gt;What is the Django admin for?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;p&gt;Thank you and see you soon&lt;/p&gt;

</description>
      <category>django</category>
      <category>node</category>
      <category>jenkins</category>
      <category>testing</category>
    </item>
    <item>
      <title>Debugging nodejs easy, simple, without complications.</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Mon, 11 Nov 2019 14:12:20 +0000</pubDate>
      <link>https://dev.to/diegoug/debugging-nodejs-easy-simple-without-complications-bnj</link>
      <guid>https://dev.to/diegoug/debugging-nodejs-easy-simple-without-complications-bnj</guid>
      <description>&lt;p&gt;The professional way to debugg an application that is running in Nodejs on the server side is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, we add the flag inspect in the command that runs our server js.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node --inpect file.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;second, in our Chrome or Chromium browser we open the url chrome://inspect/#devices and configure a new device:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdo6t79zjv50tb6jfy4oh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdo6t79zjv50tb6jfy4oh.png" alt="URL to inspect nodejs services"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Third, we configure the device in localhost and port 9229, which is the default port:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw86ybiiyyf2zosolmd5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw86ybiiyyf2zosolmd5p.png" alt="Conff debugger in chrome"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And voila, this way we can discuss our service locally:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe971p99655cht29fp5ga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe971p99655cht29fp5ga.png" alt="Debugging nodejs aplication"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we need to adjust the port, or add it to an inspector of a client such as Visual Studio Code, or stop the inspector in the first line to be able to debut before the start we can see the official documentation and these could be the results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node --inpect=0.0.0.0:9229 file.js
$ node --inspect-brk file.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://nodejs.org/de/docs/guides/debugging-getting-started/" rel="noopener noreferrer"&gt;Node.js official Debugging Guide&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the professional aspect
&lt;/h2&gt;

&lt;p&gt;There are two problems that we face when working in this way, the first is that if we want to make a change we must stop and restart our server, the second is that if the application dies we must restart our server again.&lt;/p&gt;

&lt;p&gt;To solve this problem we will use two programs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forever: your job will be to maintain and restart our nodejs server in case our application dies.&lt;/li&gt;
&lt;li&gt;Nodemon: it will be in charge of monitoring our application files in case we make any changes to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we install forever and nodemon&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install -g nodemon@1.19.4
$ npm install -g forever@1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;our server will run as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ forever -c 'nodemon --watch /opt/app --inspect=0.0.0.0:9229' file.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this we can develop faster and we will not waste time when working our service.&lt;/p&gt;

&lt;p&gt;I hope you liked the content, if you have any questions or want to write about a related topic, please leave your comment, until next time.&lt;/p&gt;

</description>
      <category>node</category>
      <category>debugging</category>
      <category>chrome</category>
      <category>chromium</category>
    </item>
    <item>
      <title>L5/Senior developer, what's next?</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Thu, 24 Oct 2019 20:30:44 +0000</pubDate>
      <link>https://dev.to/diegoug/l5-or-senior-developer-what-s-next-1jib</link>
      <guid>https://dev.to/diegoug/l5-or-senior-developer-what-s-next-1jib</guid>
      <description>&lt;h3&gt;
  
  
  Index
&lt;/h3&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Introduction

&lt;ul&gt;
&lt;li&gt;Economic awareness&lt;/li&gt;
&lt;li&gt;The personality&lt;/li&gt;
&lt;li&gt;
Point Zero
&lt;/li&gt;
&lt;/ul&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;


Introduction
&lt;/h2&gt;


&lt;p&gt;After growing up in my career through levels 1 to 5 (Junior, medium, senior), it was time to jump to a highest category, and there is a question, how to level up? At this point, when is already known that you are at a certain level, you should know how to go up to the next level, and it is important to review the lessons learned first (from my perspective) to be able to understand what is the next step and prepare for what is coming.&lt;/p&gt;

&lt;p&gt;Return to Index &lt;/p&gt;

&lt;h2&gt;
  
  
  Economic awareness
&lt;/h2&gt;

&lt;p&gt;To level up you need to be aware of how you are leading your lifestyle and how to improve it, personally, it wasn't difficult to realize that I was wrong. The problem was to fix the things or situations that was already done wrong and the biggest mistake was on the financial area, where I got into debts as soon as I got my first job. Even though I wouldn't say that I did not enjoy it but also I couldn't say that I invested that money correctly because it was for immediate pleasures.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;p&gt;In order to overcome these economic problems, the first step is to realize when this mistake is constantly being made, and when we have an inconvenience to realize about our own problems, it is important to be open minded on what others say about ourselves and to be willing to hear what their opinions. In my personal case, the first person to bring up this topic was &lt;a href="https://twitter.com/freddier"&gt;John Freddy Vega&lt;/a&gt; from &lt;a href="//www.platzi.com"&gt;Platzi&lt;/a&gt;, who says firmly that getting out of debts and having control of the economy can help us to move forward, then I started watching YouTube channels that talk about finances and good financial habits, such as &lt;a href="https://www.youtube.com/channel/UCKYJf0gOXKcOATkXvZA1crA"&gt;Paths of Success esp&lt;/a&gt; between others. &lt;/p&gt;

&lt;p&gt;The next step is to start changing financial habits and focus on paying debts without borrowing more money during the process. Hence, the reflection learned is that getting a debt can happen in a quick moment, some of those decisions can take less than 30 minutes, but paying off debts can take years.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Luke 14:28: For example, who of you wanting to build a tower does not first sit down and calculate the expense to see if he has enough to complete it?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The personality
&lt;/h2&gt;

&lt;p&gt;The second aspect that must be taken into account is how to improve our own personality, because it can always improve and it is also true that we all have defects, so it is important to constantly work this personal aspect by not thinking about pleasing other people, but realize that our personality can give a positive contribution to everyone around us.&lt;/p&gt;

&lt;p&gt;To get into details, we must take into account how we can educate ourselves in this area, as well as we can educate ourselves in the technological area in institutions like Platzi or free platforms like YouTube for financial matters. Then, to improve my personality, I realized that I need to work on my spirituality and my moral principles.&lt;/p&gt;

&lt;p&gt;The best education I found to work my personality is Biblical education, and not a moral education based on zealotry but rather an education based on principles and laws that are not difficult to accomplish in order to benefit the ones around me and myself. Also, taking into consideration that I am not judging anyone or imposing my beliefs, but without forgetting that I can educate on this path and share these benefits. In JW.org I managed learning lessons like the ones listed below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pr 22:3 The shrewd one sees the danger and conceals himself, But the inexperienced keep right on going and suffer the consequences.&lt;/li&gt;
&lt;li&gt;1 Cor 23 All things are lawful, but not all things are advantageous. All things are lawful, but not all things build up.&lt;/li&gt;
&lt;li&gt;Pr 17:9 Whoever forgives a transgression seeks love, But the one who keeps harping on a matter separates close friends.&lt;/li&gt;
&lt;li&gt;Ga 5:22,23 On the other hand, the fruitage of the spirit is love, joy, peace, patience, kindness, goodness, faith, mildness, self-control. Against such things there is no law.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meditating on these tips and many others has changed my personality for good since this education has educated me to understand that it is not only about having knowledge in technology or financial processes but in knowing how to apply this knowledge to take good decisions.&lt;/p&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;h2&gt;
  
  
  Point Zero
&lt;/h2&gt;

&lt;p&gt;The last step is to return to a zero state, which is the moment where we can start again without the world pressures such as economic responsibilities or daily labors. It is about doing something that makes you happy and to simplify life. For me, this moment has arrived, the one to keep on strengthening the lessons learned and look forward for a true happiness that consists in complaying my purpose towards God and loving others and the rest of things will be given on the way. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mt 6:33 “Keep on, then, seeking first the Kingdom and his righteousness, and all these other things will be added to you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Return to Index&lt;/p&gt;

&lt;p&gt;Thank you all who have accompanied me on what I have been on my way, and I hope to continue growing among all of you.&lt;/p&gt;

</description>
      <category>development</category>
    </item>
    <item>
      <title>Backend application + Socket.io</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Fri, 18 Oct 2019 17:50:37 +0000</pubDate>
      <link>https://dev.to/bytesizedcode/backend-application-socket-io-5405</link>
      <guid>https://dev.to/bytesizedcode/backend-application-socket-io-5405</guid>
      <description>&lt;p&gt;One of my abilities is to use socket.io along with a backend application (In this case, it is Django) to send real time events to the web browser.&lt;/p&gt;

&lt;p&gt;The key is to use socket.io as a bridge of events without over-optimizing the infrastructure, by not handling the business logic on this bridge.&lt;/p&gt;

&lt;p&gt;To perform this, It is necessary to follow the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user log in to the web application, when the backend dispatches the HTML access.&lt;/li&gt;
&lt;li&gt;The web application have to request access to the socket server.&lt;/li&gt;
&lt;li&gt;The socket server have to verify the authenticity of the user that is longing in with the backend.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The user log in to the web application, when the backend dispatches the HTML access.
&lt;/h2&gt;

&lt;p&gt;Ok, At first the backend sends the django user to redis in a temporarily form, and secures it with a key.&lt;/p&gt;

&lt;p&gt;Then, it dispatches the HTML along with the cookie that contains the key hat we used to secure the user in redis, giving as a result our template, as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IndexTemplateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TemplateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'base.html'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_context_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IndexTemplateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_context_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_access_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'Connect nodejs with your app'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_access_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_random_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'session:&lt;/span&gt;&lt;span class="si"&gt;%&lt;/span&gt;&lt;span class="s"&gt;s'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'diegoug'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IndexTemplateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;response_kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'nodejskey'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;86400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'DJANGO_SERVER_NAME'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;secure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  The web application have to request access to the socket server.
&lt;/h2&gt;

&lt;p&gt;This step is the simplest, here the HTML javascript accesses the socket server and when it accesses correctly, it displays the user name on the screen. Here the HTML code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{request.socketio}}/socket.io/socket.io.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodeServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{{request.socketio}}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodeServer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;join&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  The socket server have to verify the authenticity of the user that is longing in with the backend.
&lt;/h2&gt;

&lt;p&gt;At this point the socket server have to take the key from the cookie and take out the data of redis, if this data exists, it allows the socket to access to the connection event, sending an event to a channel that notify the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dependencies&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;socket.io&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redis&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cookie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serialize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-serialize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientRedis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REDIS_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REDIS_HOST&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;clientRedis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// module&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Socket&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOCKETIO_PORT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// run socket&lt;/span&gt;
&lt;span class="nx"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// set auth&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// when a client connects&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sockets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// event join&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;join&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handshake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// authentication&lt;/span&gt;
&lt;span class="nx"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// get cookie token&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userCookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// redis validation&lt;/span&gt;
    &lt;span class="nx"&gt;clientRedis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;session:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;userCookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodejskey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// error or not session&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Not authorized.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// config session&lt;/span&gt;
        &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unserialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handshake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YC5eJ_d1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/npjwsse2pigmnciuccx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YC5eJ_d1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/npjwsse2pigmnciuccx0.png" alt="Done"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here and on, it is a matter of managing rooms, direct messages and keep using redis to send events between the backend and the socket server using channels.&lt;/p&gt;

&lt;p&gt;An important step that needs to be done, is to verify the domain from where the user try to log in the socket, to avoid impersonation of the real user identity.&lt;/p&gt;

</description>
      <category>node</category>
      <category>websocket</category>
      <category>socketio</category>
    </item>
    <item>
      <title>What is the Django admin for?</title>
      <dc:creator>Diego Uribe Gamez</dc:creator>
      <pubDate>Fri, 18 Oct 2019 17:50:20 +0000</pubDate>
      <link>https://dev.to/diegoug/what-is-the-django-admin-for-5deh</link>
      <guid>https://dev.to/diegoug/what-is-the-django-admin-for-5deh</guid>
      <description>&lt;p&gt;In Django one of the least explored parts in documentation and by users is the Django Admin, this one with great capabilities and certain characteristics, but to be a 100% viable option these must be worked at the level of user experience, and this Is the reason for its unpopularity, of there is the question, what is the admin Dajngo for? its viable?&lt;/p&gt;

&lt;p&gt;In essence, the admin of Django is a web interface to manage database models, in this interface you can create, view, modify and delete data from the database, as well as special operations that are also related to the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  When we don't need an admin?
&lt;/h2&gt;

&lt;p&gt;We do not need it when from the web client we can manage all or most of the essential data of our application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can admin do for you?
&lt;/h2&gt;

&lt;p&gt;If we think about it by observing the previous paragraph, we could conclude that there could be data that the client does not necessarily have to administer or that need to be managed, where an administrator on a different platform could manage it, this is the simplest use that could be given to this tool.&lt;/p&gt;

&lt;p&gt;This makes the Django admin perfect for an MVP, where the client does not necessarily manage all the data, or because initially all the administration interfaces cannot be created, and the data needs to be managed by the different areas of the company such as the operators, the product team, marketing, etc, and there is where the admin comes into action, since with some lines of code you can reach good administration interfaces for the data.&lt;/p&gt;

&lt;p&gt;But if it is so good for this because it is not used or contemplated on a regular basis to work as administration interfaces, both on the side of customers and operators? Basically because this administrator is very attached to the data side, and its incorrect administration or programming could lead to security breaches, system failures, or an intuitive interface, that is why it is not recommended to enable it for end customers of no way.&lt;/p&gt;

&lt;p&gt;Already knowing all this, and assuming that we are willing to take responsibility, can we use it? The answer is yes, and it is important that if we want to use it we must take into account the following aspects:&lt;/p&gt;

&lt;h2&gt;
  
  
  The models and their information architecture.
&lt;/h2&gt;

&lt;p&gt;It is very important to plan very well how the data will be structured even before throwing a line of code, this will affect the future development, the administration interface since this is reactive to the data, and above all it will affect the data. customers who consume our data.&lt;/p&gt;

&lt;p&gt;Warning: an important functionality is the nested forms, these can show in a single view a lot of information towards a parent, their relationship is from children to the father, the problem with these views is that if there is a lot of nested information the template engine becomes a bottleneck since this is very slow to show a lot of data, and the performance will be much more impacted when there are children related to children and these with parents.&lt;/p&gt;

&lt;h2&gt;
  
  
  User permission management.
&lt;/h2&gt;

&lt;p&gt;In this part, django admin is very good at creating a database record to manage groups and users, giving permissions to models at the level of reading, writing and modification, and according to what permission the user has, the interface adapts to Provide the options available to that particular user.&lt;/p&gt;

&lt;p&gt;It is also important that if we want a user model with additional information other than what it already brings natively, what we need is to create a new model that inherits the native and add those fields, then tell the admin to use this model to manage the users.&lt;br&gt;
Programmable Administrator&lt;/p&gt;

&lt;p&gt;By default the django admin does not show the information just by creating the models, even the administrator access url is not programmed by default, the administrator interface must be all programmed using the options addressed to the admin that the Django team gives us in its documentation, and the interface will react to the programmed options, from the presentation of the texts, the search or indexing of information, the amount of information and how it is shown to the administrator must be programmed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customize the options that the Django team gives us.
&lt;/h2&gt;

&lt;p&gt;This is where things get a bit complicated, because to be able to modify the way in which the native options that are given to us to program the administrator what we have to do is intervene the django admin's functionalities, when I mean intervene it means modifying or replace the functionalities to deliver the same data structure and that the administrator does not break because later functionalities expect a unique data structure, unless we also intervene that other functionality, to do this there are documentation and several examples of troubleshooting on the Internet , you also need to have more or less advanced knowledge of Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the django admin do more or change the way he does things.
&lt;/h2&gt;

&lt;p&gt;Here everything is much more complicated, and it is important to have advanced knowledge of Python as of the framework, since this is to make the admin do things for which it is not yet done, an example can be a confirmation window, a possible way If this is done, it would be necessary to extend the urls of the Django admin by associating it with a view with a form, this view must receive the request and show a confirmation view, at the time of confirming the action this view must post its own form url with the data necessary to continue the action, this in detail does not have the admin by default and to build it requires to have good programming knowledge.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
    </item>
  </channel>
</rss>
