Monday, February 22, 2021

Debug Laravel / PHP applications with XDebug in VSCODE

We will setup debugging using xdebug with PHP inside of visual studio code. 

Quick setup:

1) install php-xdebug:

sudo apt install php-xdebug

2) inside of php.ini at the end of the file set: 

[xdebug] 

xdebug.start_with_request = yes 

xdebug.mode = debug 

xdebug.discover_client_host = false 

3) install php debug extension in VSCODE and set the port of the vscode php debug extension to 9003.

Now you can press F5 and start debugging.

 

 

 

Alternatively you can install xdebug using pecl. 

The setup is valid for Ubuntu both on bare-metal as well as under Windows 10 with WSL.

Enjoy !

Sunday, September 27, 2020

JWT - JSON WEB TOKENS security

Refresh tokens are helpful stateless technology, because they have longer time of expiry than the secure tokens, and can be used to send requests back to the server for reissuing of normal secure tokens. 

The primary aim of a refresh token is to regenerate the authentication for the user in such way, that the user doesn't need to manually re-login into the system.

The flow of using refresh together with secure tokens is the following: Initially we're making a request containing valid combination of user/password payload to a server. After performing checks the server is generating and returning to us a pair of secure and refresh tokens. It is sending the refresh token as an http only cookie, which cannot be read or modified by the browser. Later in the process of work, when the secure token is about to expire we use the cookie containing the refresh token information to make request to the server. The server checks its validity in its database and sends back to the client a new pair of refresh secure tokens. 

In summary we use refresh tokens when our access token is expired, and we would like to renew it as well as to renew the refresh token. That is why it has longer expiration time than the access token. Keep in mind that, when the refresh token is expired we need to manually re-login the user. For the technical implementation of refresh tokens is very good if you manage to place the refresh token inside of http-only cookie, because on the client side JavaScript and other techniques cannot exploited to modify this type of cookie. In rare cases, if attackers send a refresh request to the server they cannot get the newly issued secure token. If you would like to increase the security of the generated tokens you can also include browser and os fingerprinting inside of the token payload. 

For the authentication server it is good it can perform the following specific actions: to be able to generate access and refresh tokens to revoke tokens(to delete the refresh token). When a refresh token is generated it usually goes through the following process: check whether there is an user id in the internal database with a token, check the validity of the token, check the number of tokens for this user: how many they are, because one user can generate and overflow our database and this is also a type of an attack. When everything is ready we can save the newly generated token into our database.


 

Access token is used when performing service requests

secret key is stored both in the server and in the JWT payload:
const Token = jwt.sign(
{ user: myUser }, // payload
jwtSecretKey,
{ expiresIn: '30d' }
);
on client side resides in local storage

 

1) Client side authentication - POST request to get the token:
payload: {
‘username:req.body.user’,
’password:req.body.password’
}

Response
Bearer: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwMSIsIm5hbWUiOiJKb2huIERvZSIsImlhdC

2) Client side: request + Authorization header
fetch(url, {
        method: 'GET',
        withCredentials: true,
        credentials: 'include',
        headers: {
            'Authorization': bearer,
        }
    })

request service with the token:
3) Server side authorization -
// const token = req.get('Authorization');
// token = token.slice(7, token.length);

app.route(‘/secret_url’).post(
jwtVerifier,
(req,res)=>res.send(‘info’)); // secret information

 


Refresh token is used when access token is expired in order to produce new access and refresh tokens.

  • has longer expire time than the access token, if expires the user is logged out.
  • on client side resides in httponly cookie, so client cannot modify it (attacker cannot get the new JWT refresh token)
  • includes browser fingerprint for extra security


The auth server can perform specific actions:

  • generate new access and refresh tokens
  • refresh tokens:
    •  check the user_id from the http transmitted refresh token cookie against internal refresh tokens list in order to regenerate new access & refresh tokens:
      • check refresh token validity (by comparing user_id inside the issued token list for the requested user)
      • prune the number of generated refresh tokens (because the user can be logged in from different devices)
      • save in a db the generated refresh tokens
  • revoke token (delete refresh token)

The practical implementation of both JWT secure and refresh tokens can be seen in these 2 courses:

Angular with PHP and JSON web tokens (JWT)

JavaScript User Authentication Login Script (JWT)

 

Congratulations !

 

Sunday, September 20, 2020

Starting with React


Here is how to create a simple application with the React front-end framework:


 

Setup the project:

sudo npm i -g create-react-app // install the dependencies
npx create-react-app my-react-app // create the initial application
npm start //start the live development server


App.js
import React from 'react';
import './App.css';
import Login from './loginComponent'; //default import
import {UsersList} from './usersList'; // specific import

const users = [ // using nested/presentational components
{ name: 'John', occupation: 'student', age: 23 },
{ name: 'Pete', occupation: 'teacher', age: 30 },
{ name: 'Anna', occupation: 'programmer', age: 35 }
];

const App = () => {
// double curly braces because of passing object and because of passing property
return (
<div className="App">
<Login user={{ name: "John", uid: 1000 }} />
<header className="App-header">
<UsersList users = {users} />
</header>
</div>
);
}

export default App;


usersList.js
import React from 'react';
import {UsersListItem} from './usersListItem'; // specific import

export const UsersList = ({ users }) => // getting especially users array from the passed array with props
( // with () we return automatically instead of writing {}
<>
{ users.map(user => <UsersListItem user={user} key={user.name} /> ) }
</>
);
// React will be used when we return react fragment


usersListItem.js
import React from 'react';
const sayMyName = (name) => {
alert(name);
}

export const UsersListItem = ({ user }) =>
(<div>
{user.name} -
{user.occupation} -
{user.age}
<button onClick={ ()=>sayMyName(user.name) }>Display name</button>
</div>
)


loginComponent.js
import React from 'react';
// show the import, conditionals and DOM element, also the export
// how to display props, destructurise in the passing parameters(props)

const Login = ({ user }) => {
let isAdmin = (user.uid) === 1000;
let logged_in = true;
// double conditional
return logged_in ? (
<>
hello mr.{user.name}
{ isAdmin ? `you are admin (conditional)` : null}
</>
)
: (<>please login</>)
}

export default Login;

Tuesday, September 15, 2020

Deploy Angular app to Vercel and Firebase for free

Here is how to do it very quickly:


 

For Firebase you'll need to install the following schematics:
ng add @angular/fire

then just do:
ng deploy

you'll be probably asked to authenticate with password in browser, and then your project will be on Internet.

If you would like to youse serverless functions for NodeJS interpretation here is the way:
sudo npm install -g firebase-tools 

firebase init functions

This will install and initialize the functions. Then go to the newly created /functions directory and install your packages such as: npm install nodemailer cors etc.

And now is time to edit the auto-generated index.js file.

When you are happy with the generated function you can deploy it, just run from the same directory: 

firebase deploy

For Vercel, after the registration just link your github repository to Vercel. You can see/edit your current local git configuration with:

git config --local -e

To link the remote origin of your repository to the local git repo use: 

git remote add origin  https://github.com/your_username/project.git

if there is something on the remote site, you can overwrite it with the local version using:
git push --set-upstream origin master -f

 
or just pull and merge the remote version: git pull origin master

Then just do your commits and when pushing you'll have a new version synchronized in Internet.

Congratulations and enjoy the: Angular for beginners - modern TypeScript and RxJS course!

Sunday, September 13, 2020

Web development in LXC / LXD containers on Ubuntu

Here is how to do web development using the very fast Ubuntu native LXC/LXD containers. Part of the Practical Ubuntu Linux Server for beginners course.



First lets install lxd in our system:
sudo snap install lxd

Then initialize the basic environment:
sudo lxd init

We will also fetch image from a repository: linuxcontainers.org

and will start a container based on it:
sudo lxc launch images:alpine/3.10/amd64 webdevelopment

Let's see what we have in the system:
sudo lxc ls
sudo lxc storage ls
sudo lxc network ls

Now it is time to access the container with: sudo lxc exec webdevelopment sh
and then we will use apk to install openssh
apk add openssh-server
lets' also add unprivileged user in order to access the ssh:
adduser webdev

we will also start the server: 

service sshd start

Ok let's check with: ip a the address of the container.

Now we exit the shell(sh) and we can connect to the container using our new user: ssh webdev@ip address of container

Alright, now go back inside the container and will add the Apache service:
apk add apache2
service apache2 restart

Optional:

If we need to get rid of the container we need to stop it first:
sudo lxc stop demo
sudo lxc delete demo

If we need to get rid of the created storage pool, we run the following:
printf 'config: {}\ndevices: {}' | lxc profile edit default
lxc storage delete default

If we need to remove the created network bridge we can run:
sudo lxc network delete lxdbr0

Congratulations and happy learning !

Tuesday, September 01, 2020

Skaffold on microk8s kubernettes

Here is how to install configure and use microk8s with skaffold, step by step. Based on the Kubernetes course:

installation:

curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && sudo install skaffold /usr/local/bin/

create the initial project skaffold configuration:

skaffold init 



create alias to kubectl for skaffold to be able to use it :  

sudo snap alias microk8s.kubectl kubectl

provide microk8s config to skaffold:

microk8s.kubectl config view --raw > $HOME/.kube/config

update the pod configuration to use the image from microk8s:

image: localhost:32000/php-app 

(add localhost:32000...)

enable microk8s registry addon: 

microk8s.enable registry
then test the registry if it works: http://localhost:32000/v2/

run skaffold monitoring by providing repo to the insecure microk8s repo:

skaffold dev --default-repo=localhost:32000
Check if the pod is running:

kubectl get pods

Expose the pod ports to be browsable:

kubectl port-forward pod/skaffold-pod 8080:4000

Optional: In case we need to debug inside the container:   

docker run -ti localhost:32000/php-app:latest /bin/bash


Congratulations and enjoy the course !

Monday, August 24, 2020

Install phpmyadmin in Ubuntu 20.04

Here is how to install phpmyadmin on Ubuntu 20.04
References: Practical Ubuntu Linux Server for beginners

We need fist to have mysql-server installed, where phpmyadmin will store its data. For this reason we will run:
sudo apt install mysql-server

Then some libraries for the functioning of phpmyadmin as well as the phpmyadmin package:
sudo apt install phpmyadmin php-mbstring php-zip php-gd php-json php-curl php libapache2-mod-php
Note: if there is a problem in the installation you can Ignore, or Abort the configuration of phpmyadmin.

Let's now go and login inside of MySQL as root:
sudo mysql -u root 


or if you already have password/user then: login with: sudo mysql -u user -p

Next we will adjust the MySQL root password, as well as its method of authentication:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Optional: 

Configure Apache in order to serve phpmyadmin (if not already done by installation of phpmyadmin): inside of etc/apache/conf-available/ we create the following phpmyadmin.conf file:

Alias /phpmyadmin /usr/share/phpmyadmin
<Directory /usr/share/phpmyadmin/>
   AddDefaultCharset UTF-8
   <IfModule mod_authz_core.c>
      <RequireAny>
      Require all granted
     </RequireAny>
   </IfModule>
</Directory>
 
<Directory /usr/share/phpmyadmin/setup/>
   <IfModule mod_authz_core.c>
     <RequireAny>
       Require all granted
     </RequireAny>
   </IfModule>
</Directory>


Lastly, we need to activate the above configuration file with:
a2enconf phpmyadmin.conf
and then restart the apache2 service to reload and accept the changed configuration:
sudo systemctl restart apache2.service

Now is time to open up in the browser to: http://127.0.0.1/phpmyadmin
and use the combination that we already set: root / password

Congratulations and enjoy learning !

Subscribe To My Channel for updates