<?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: Vasilis Zoumpourlis</title>
    <description>The latest articles on DEV Community by Vasilis Zoumpourlis (@vzuburlis).</description>
    <link>https://dev.to/vzuburlis</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%2F45241%2F36bda42f-db88-4e31-8214-1fe6bac43e41.jpg</url>
      <title>DEV Community: Vasilis Zoumpourlis</title>
      <link>https://dev.to/vzuburlis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vzuburlis"/>
    <language>en</language>
    <item>
      <title>Using Gila CMS as a back-end service</title>
      <dc:creator>Vasilis Zoumpourlis</dc:creator>
      <pubDate>Tue, 21 Apr 2020 09:40:05 +0000</pubDate>
      <link>https://dev.to/vzuburlis/using-gila-cms-as-a-back-end-service-1ikg</link>
      <guid>https://dev.to/vzuburlis/using-gila-cms-as-a-back-end-service-1ikg</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/gilacms/gila"&gt;Gila CMS&lt;/a&gt; is a content management solution I am building the last few years. It started as an open source project that would give the ability to small businesses to build customized and flexible applications.&lt;/p&gt;

&lt;p&gt;One of the advantages is that Gila also works as a headless cms. In this article I will show you how you can create a new database table and how to use the data in your web application. The examples will be shown with the &lt;a href="https://github.com/axios/axios"&gt;axios&lt;/a&gt; library.&lt;/p&gt;

&lt;p&gt;To continue you need Gila CMS &lt;a href="https://gilacms.com/docs/install.html"&gt;installed&lt;/a&gt; on your server. In the administration menu, go to &lt;strong&gt;Administration-&amp;gt;Settings&lt;/strong&gt; and set Environment to "Development", so you can make changes in your code and they apply directly.&lt;/p&gt;

&lt;p&gt;The first thing to do is create a new package to add our code. Inside the &lt;em&gt;src&lt;/em&gt; folder create a new folder &lt;em&gt;my-movies&lt;/em&gt;. Inside the &lt;em&gt;my-movies&lt;/em&gt; add the following four files:&lt;br&gt;
&lt;em&gt;package.json&lt;/em&gt;&lt;br&gt;
&lt;em&gt;tables/movie.php&lt;/em&gt;&lt;br&gt;
&lt;em&gt;load.php&lt;/em&gt;&lt;br&gt;
&lt;em&gt;update.php&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;package.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "My Movies Package",
  "version": "1.0.0",
  "description": "Adds a table to store your favorite movies"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;tables/movie.php&lt;/strong&gt;&lt;br&gt;
In this schema note the &lt;strong&gt;permissions&lt;/strong&gt; attribute: By default, all permissions require the admin user role, but for the read permission we set value true, so the data can be read from axios without a logged in user. More information about table schema you can find in &lt;a href="https://gilacms.com/docs/schemas.html#table-schema"&gt;documentation&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

return [
  "name"=&amp;gt; "movie",
  "tools"=&amp;gt; ["add"],
  "commands"=&amp;gt; ["edit","delete"],
  "permissions"=&amp;gt;[
      "read"=&amp;gt;true
  ],
  "fields"=&amp;gt; [
  "id"=&amp;gt; [
      "edit"=&amp;gt; "false"
    ],
    "title"=&amp;gt; [
      "qtype"=&amp;gt; "VARCHAR(120)"
    ],
    "score"=&amp;gt; [
      "type"=&amp;gt; "select",
      "options"=&amp;gt; [1=&amp;gt;"1",2=&amp;gt;"2",3=&amp;gt;"3",4=&amp;gt;"4",5=&amp;gt;"5"],
      "qtype"=&amp;gt; "TINYINT DEFAULT 1"
    ],
    "poster"=&amp;gt; [
      "type"=&amp;gt; "media",
      "qtype"=&amp;gt; "VARCHAR(120)"
    ]
  ]
];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;load.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

Gila::content('movie', 'my-movies/tables/movie.php');
Gila::amenu_child('content', ['My Movies','admin/content/movie','icon'=&amp;gt;'play','access'=&amp;gt;'admin']);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;update.php&lt;/strong&gt;&lt;br&gt;
This file runs in activation of the package and will create the table in the database for us&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

Gila::content('movie', 'my-movies/tables/movie.php');
$gtable = new gTable('movie');
$gtable-&amp;gt;update();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After you have all files in place, you go to &lt;strong&gt;/admin/packages&lt;/strong&gt; and activate the package &lt;em&gt;My Movies&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then in the administration go to &lt;strong&gt;Content-&amp;gt;My Movies&lt;/strong&gt; and you will see the new table with the button "+New" to add your movies. Here is a screenshot with a few registries.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rXva-e0Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/32rcgxcf9odkhyzp2l3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rXva-e0Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/32rcgxcf9odkhyzp2l3x.png" alt="Movies table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the data that you add in the table, you can get them from your app with ajax requests or promises. If your app runs from a different domain of Gila website you have to set the cors in config.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
"cors"=&amp;gt; [
  0=&amp;gt; 'https://my-app-domain.com'
]
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Axios requests
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Get all movies
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;axios.get('/cm/list/movie').then(function (response) {
  console.log(response);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    {
        "id": "3",
        "title": "Captain America: Civil War",
        "score": "4",
        "poster": "assets/movies/captainamericacivilwar_lob_crd_01_9.jpg"
    },
    {
        "id": "2",
        "title": "Ant-Man",
        "score": "3",
        "poster": "assets/movies/ant-man_lob_crd_01_8.jpg"
    },
    {
        "id": "1",
        "title": "Troy",
        "score": "2",
        "poster": "assets/Troy.jpg"
    }
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Get movie by id
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;axios.get('/cm/list/movie?id=2').then(function (response) {
  console.log(response);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Search movies
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;axios.get('/cm/list/movie?search=Man').then(function (response) {
  console.log(response);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Get movies with score greater than 3, and ordered by title
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;axios.get('/cm/list/movie?score[gt]=3&amp;amp;orderby[title]=ASC').then(function (response) {
  console.log(response);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Get only title and poster of the movies
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;axios.get('/cm/list/movie?select[]=title&amp;amp;select[]=poster').then(function (response) {
  console.log(response);
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;More information for the &lt;strong&gt;/cm&lt;/strong&gt; endpoint and its parameters you can find in &lt;a href="https://gilacms.com/docs/cm.html#cm-list-rows"&gt;documentation&lt;/a&gt; pages.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>php</category>
      <category>cms</category>
      <category>api</category>
    </item>
    <item>
      <title>Secure better your website with SameSite cookies</title>
      <dc:creator>Vasilis Zoumpourlis</dc:creator>
      <pubDate>Mon, 11 Nov 2019 05:39:03 +0000</pubDate>
      <link>https://dev.to/vzuburlis/secure-better-your-website-with-samesite-cookies-33po</link>
      <guid>https://dev.to/vzuburlis/secure-better-your-website-with-samesite-cookies-33po</guid>
      <description>&lt;p&gt;Cross-site request forgery (CSRF) attacks is a type of malicious exploit of a website where unauthorized commands are transmitted from a user that the web application trusts.&lt;/p&gt;

&lt;p&gt;Let's see the following example: You have an endpoint that updates a user: &lt;em&gt;mysite.com/user/update/2&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The new data should come from a POST method, so if you open the endpoint from a  link, the update will not happen because the request method in this case is GET. But someone could build this simple html file:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This &lt;em&gt;index.html&lt;/em&gt; can be placed in any website (like clickhereandseewhathappens.com), and the link is send it to the website administrator with an email. When the administrator opens this html in the browser, the form will be submited to mysite.com and the user will be updated.&lt;/p&gt;

&lt;p&gt;This will happen because the &lt;em&gt;sessionId&lt;/em&gt; cookie of the user will be sent to the server and the application understands that this request was made from the administrator.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;SameSite&lt;/strong&gt; is a cookie key that tells browser to send the cookie value to the server only when the request is made from the same domain of the website.&lt;/p&gt;

&lt;p&gt;For example, when you dont want to sent the cookie from a different  url.&lt;/p&gt;

&lt;pre&gt;mycookie=value; expires=Wen, 1 Jan 2019 12:00:00 UTC; path=/; SameSite=Strict&lt;/pre&gt;

&lt;p&gt;When you want to send it with simple links (GET method) but not with POST/PUT/DELETE etc&lt;/p&gt;

&lt;pre&gt;mycookie=value; expires=Wen, 1 Jan 2019 12:00:00 UTC; path=/; SameSite=Lax&lt;/pre&gt;

&lt;p&gt;The default scenario is to sent it always. &lt;/p&gt;

&lt;p&gt;This feature is already supported from all major browsers &lt;a href="https://caniuse.com/#feat=same-site-cookie-attribute"&gt;https://caniuse.com/#feat=same-site-cookie-attribute&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So this is an extra layer of security for your website and very easy to implement.&lt;/p&gt;

&lt;p&gt;To create a samesite cookie with php:&lt;/p&gt;

&lt;pre&gt;header("Set-cookie: mycookie=value; path=/; HttpOnly; SameSite=Lax");&lt;/pre&gt;

&lt;p&gt;From php 7.3 you can use setcookie function with the options (8th) parameter:&lt;/p&gt;

&lt;pre&gt;setcookie('mycookie', 'value', time()+86400, '/', null, null, true, ['samesite'=&amp;gt;'Strict']);&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the above examples also adds the &lt;strong&gt;HttpOnly&lt;/strong&gt; key for the cookie, that key prevents from your javascript to access the value of your cookie. So even you have a XSS script run in your website, it wont be able to see the cookie's value.&lt;/p&gt;

&lt;p&gt;To set the expiration date with header() you must print date with the expected format&lt;/p&gt;

&lt;pre&gt;
$expire = date('D, d M Y H:i:s', time() + (86400 * 30)); // one month from now
header("Set-cookie: mycookie=value; expires=$expire; path=/; HttpOnly; SameSite=Lax");
&lt;/pre&gt;

</description>
      <category>php</category>
      <category>security</category>
    </item>
  </channel>
</rss>
