Sunday, 30 April 2023

Three ways to create an instance of class in Laravel


interface SomeInterface {
public function doSomething();
}

class SomeImplementation implements SomeInterface {
public function doSomething() {
echo "Did something!\n";
}
}

1. Using 'bind'

- to register ad binding with service container, the container resolve an instance of class, allow to manage class dependencies and customize the instantiation process

// Bind the interface to an implementation in the service container
$this->app->bind(SomeInterface::class, SomeImplementation::class);

2. Using 'resolve' 

- to resolve an instance from the container, the container resolve an instance of class, allow easily access and use object

// Resolve an instance of the implementation from the container
$implementation = resolve(SomeInterface::class);
// or
$implementation = resolve(SomeImplementation::class);
// using
$implementation->doSomething(); // Output: "Did something!"

3. Using 'new'

-  to create a new instance directly, don't use service container

// Create a new instance of the implementation using the "new" keyword
$implementation = new SomeImplementation();
$implementation->doSomething(); // Output: "Did something!"

 Thank you. 

Monday, 24 April 2023

Questions for Interviewing Vuejs

1. Can you explain what Vue.js is and how it differs from other JavaScript frameworks?

2. What are some of the advantages of using Vue.js?

3. Can you walk me through the lifecycle hooks in Vue.js?

4. How does Vue.js handle component communication?

5. How do you handle errors and debugging in Vue.js?

6. Can you talk about the concept of reactivity in Vue.js and how it works?

7. How does Vue.js handle state management?

8. What are some of the most popular tools and libraries used with Vue.js?

9. Can you describe the process of creating a simple Vue.js app from scratch?

10. What are some common challenges you've faced while working with Vue.js, and how have you overcome them?

Thank you



Sunday, 23 April 2023

Apply SOLID principles in PHP

1. Single Responsibility Principle 

- Each class should have only one responsibility

class User extends Model{}

class EmailNotifier {
public function send(User $user, $message) {}
}

// in your controller or service class
$user = User::find($id);
$user->update($request->all());

$emailNotifier = new EmailNotifier();
$emailNotifier->send($user, 'Your information has been updated.');

2. Open/Closed Principle 

- A class should be open for extension but closed for modification

interface PaymentGatewayInterface { public function processPayment($amount);}

class PayPalGateway implements PaymentGatewayInterface {
public function processPayment($amount) {}
}

class StripeGateway implements PaymentGatewayInterface{
public function processPayment($amount) {}
}

class PaymentController extends Controller{
public function process(Request $request, PaymentGatewayInterface $gateway) {}
}

3. Liskov Substitution principle

- Each base class can be replaced by its subclasses

abstract class EmailProvider {
abstract public function addSubscriber(User $user): array;
abstract public function sendEmail(User $user): void;
}

class MailChimp extends EmailProvider {
public function addSubscriber(User $user): array {}
public function sendEmail(User $user): void {}
}

class ConvertKit extends EmailProvider{
public function addSubscriber(User $user): array {}
public function sendEmail(User $user): void {}
}

// you can using baseclass
class AuthController {
public function register(RegisterRequest $request,
EmailProvider $emailProvider) {}
}

// or using subclasses
public function register(RegisterRequest $request,
ConvertKit $emailProvider) {}

* apply: use type, hints and return types, use default values for parameters => to would be immediately flag the error when wrong types

4. Interface Segregation Principle

- Should have many small interfaces instead of a few huge ones 

// not do like this  
interface ProductType{
public function calculatePrice(Product $product): float;
public function decreaseInventory(Product $product): void;
public function calculateTaxes(Product $product): TaxData;
}

// apply Interface Segregation Principle
interface ProductPriceType{
public function calculatePrice(Product $product): float;
}

interface ProductInventoryHandler{
public function decreaseInventory(Product $product): void;
}

interface ProductTaxType{
public function calculateTaxes(Product $product): TaxData;
}

5. Dependency Inversion Principle

- Depend on abstraction, not detail

abstract class MarketDataProvider{
abstract public function getPrice(string $ticker): float;
}

class IexCloud extends MarketDataProvider{
public function getPrice(string $ticker): float {}
}

class Finnhub extends MarketDataProvider {
public function getPrice(string $ticker): float {}
}
 
// using
MarketDataProvider
class CompanyController {
public function show( Company $company,
MarketDataProvider $marketDataProvider) {}
}

Thank you.

References
- https://martinjoo.dev/solid-principles-with-laravel


Saturday, 22 April 2023

What are some best practices for optimizing SQL queries in Laravel?

1. Use eager loading: Eager loading allows you to retrieve related models in a single query, rather than making separate queries for each related model. This can help reduce the number of queries and improve performance. You can use the with method or the eagerLoad method to specify which related models to load.

2. Use the query builder: The query builder provides a convenient way to construct SQL queries using a fluent, chainable syntax. It also supports parameter binding to help protect against SQL injection attacks.

3. Avoid the n+1 query problem: The n+1 query problem occurs when you retrieve a collection of models, and then make separate queries to retrieve related models for each item in the collection. This can result in a large number of queries and slow performance. To avoid this problem, use eager loading or the load method to retrieve related models for the entire collection in a single query.

4. Use indexes: Indexes can help speed up queries by allowing the database to quickly locate rows that match a certain condition. You can add indexes to columns using Laravel migrations or directly in the database.

5. Use pagination: If you're retrieving a large number of records, consider using pagination to limit the number of records retrieved and improve performance. Laravel provides a convenient pagination method that you can use with the query builder.

6.
Avoid unnecessary columns: When retrieving records, only select the columns that you need. This can help reduce the amount of data that needs to be retrieved and improve performance.

7. Use caching: If your queries are relatively static, you can consider using caching to avoid the overhead of querying the database repeatedly. Laravel provides a caching system that you can use to cache query results.

8. Monitor query performance, check the condition where: Use tools such as the Laravel Debugbar or the Query Monitor plugin to monitor query performance and identify slow or inefficient queries. This can help you optimize your queries and improve performance.

By following these best practices, you can optimize your SQL queries in Laravel and improve the performance of your application.


Thank you.

Wednesday, 12 April 2023

What is Async local storage in Adonis

>> Official Guide

- Async Local Storage store in ram?

+ The Async Local Storage in AdonisJS stores data in memory, which means that it is volatile and the data will be lost when the process or server is restarted. The Async Local Storage API uses the AsyncLocalStorage class from the Node.js async_hooks module, which provides a way to create and manage a separate storage area for each execution context in a Node.js application.  

+ The Async Local Storage stores data in the current execution context, which means that it can be accessed within the same request or job, but not across different requests or jobs. The Async Local Storage is useful for storing data that is specific to a particular execution context, such as data associated with a particular user or session, or data that is generated during the processing of a particular request or job. However, it's important to note that the data stored in the Async Local Storage is not persistent and will be lost when the execution context is destroyed.

- Async Local Storage like vuex in nuxtjs and redux in react?

+ There are similarities between Async Local Storage in AdonisJS and state management libraries like Vuex in Nuxt.js and Redux in React.

+ Async Local Storage is a mechanism for storing data in the current execution context, which is similar to how state management libraries like Vuex and Redux store data in a centralized state store that can be accessed and modified by different parts of an application.

+ The main difference is that Async Local Storage is designed specifically for server-side Node.js applications, while Vuex and Redux are designed for client-side web applications. Async Local Storage allows you to store data that is specific to a particular execution context, such as data associated with a particular user or session, while Vuex and Redux allow you to store and manage application-level state that can be shared between different components.

- Async Local Storage like context in nuxtjs?

+ Async Local Storage in AdonisJS is similar to the context object in Nuxt.js.

+ Both Async Local Storage and the context object provide a way to store and share data across different parts of an application. Async Local Storage is used to store data within the current execution context in a Node.js application, while the context object is used to pass data between different parts of a Nuxt.js application, such as middleware, plugins, and pages.

+ The main difference between Async Local Storage and the context object is that Async Local Storage is specific to a particular execution context within a Node.js application, while the context object is specific to a particular request within a Nuxt.js application.

Thank you.  

Differences using Session and Cache in Laravel

1. Session 

- user_unique_session_id: each user session is associated with a unique session ID that is stored as a cookie on the user's browser.
- session data can be store in file, redis, database in hard disk...(by driver)
- throught user_unique_session_id, server can get session data

- notes: can NOT be used to store data that is specific to an asynchronous operation: in a background job can NOT access session data, because cannot access the session ID that is stored on the client-side

2. Cache 

- save data by key: value

- cache data can be store in file, redis, database in hard disk...

- note: can be accessed by any part of your application, including background jobs and other asynchronous tasks.

Learn more

* how laravel generate unique session IDs

- Laravel use the Illuminate\Session\Store class, which provides a variety of methods for managing and manipulating session data.

- By default, Laravel generates a new session ID for each user session using a cryptographically secure random string generator. The specific method used to generate the session ID varies depending on the driver used for session storage, but typically involves generating a random string of sufficient length and complexity to prevent guessing or brute-force attacks.

- Once the session ID has been generated, it is stored in a cookie on the user's browser. The cookie typically has a short lifespan, usually 20-30 minutes by default, after which it expires and the user must re-authenticate to continue their session.

- It's worth noting that Laravel provides various configuration options for session management, including the ability to customize the session ID generation algorithm and the session cookie settings. This allows developers to fine-tune the session management behavior of their application to best fit their specific needs and requirements.

 

Thank you.

 

Tuesday, 11 April 2023

How to use @adonisjs/lucid

>> Official Guide

>> Github commit

1. setup package

npm i @adonisjs/lucid

- configure package

node ace configure @adonisjs/lucid

2. Make migration

node ace make:migration <table_names>

 

Thank you.  

Monday, 10 April 2023

How to use OWASP ZAP with Json based authentication to test API

1. Install demo app to test

- install Docker

- run command

docker run -d -p 3000:3000 bkimminich/juice-shop

- can access page frontend: localhost:3000

 

2. Open OWASP ZAP enter url page want to test

- Quick Start > Url to explore > Enter Url: localhost:3000 > Launch Browser 

(if there are errors in launch browser then change config brower version in OWASP equal version your Chrom browser)

* You also call API by using Postman (config Postman proxy with OWASP ZAP)


3. Register account

Email: test@test.com Password: testtest


4. Login account

Email: test@test.com Password: testtest

Access pages in apps


5. Open OWASP ZAP you will see page history you accessed

- Below image is request call api whoami when you not logged http://localhost:3000/rest/user/whoami it will reuturn user null.

- Below image is request to call API login http://localhost:3000/rest/user/login witll return lại token 

- Below image is request call api whoami when you logged http://localhost:3000/rest/user/whoami it will reuturn user info

6. Include site context localhost:3000

- Right Click site localhost:3000 > Include Site in Content > New Context

Rename context name become JsonBaseAuth (any name you want) > Click Ok


8. Dedicate login để authentication

Click Request call API Login > Flag as Context > JsonBasedAuth JSON-based Auth Login Request

Check config again to equals with below image > Click Ok


9. Add User for OWASP ZAP using login when test

- Double Click contexts JsonBaseAuth > Users > Enter User Credential > Add > Click Ok


10. Add Session Management Script for OWASP ZAP get token khi gọi API login

- Double Click on Scripts > Session Management > Enter config for Script like below image
(name: SessionScriptJShop.js) > Save > Click Ok

* Note: According data return access token can be with name “token”, or “access_token”
(according server api), like below config that will get variable token with name “token”,
if server return access token with orther name you have to option SessionScriptJShop.js file

- Save script file: right click file SessionScriptJShop.js > Save Script > Save


10. Load SessionScriptJShop.js for OWASP ZAP

- Double Click into contexts JsonBaseAuth > Session Management > select Script-based
Session Management > Select File SessionScriptJShop.js > Click Load > Click Ok


11. Set logged-in indicator

Right Click request gọi api whoami when logged http://localhost:3000/rest/user/whoami 

> select tab Respone 

> Selected text ‘email’

> Right Click into text email 

> Flag as Context 

> JsonBaseAuth: Authentication Logged-in indicator

Chỉnh lại cấu hình như hình bên dưới > Click Ok


12. Set logged-out indicator

Righ click request call api whoami when not logged http://localhost:3000/rest/user/whoami 

> select tab Respone 

> select all text response

> Right click

> Flag as Context 

> JsonBaseAuth: Authentication Logged-out indicator

Check config like below image > click Ok


13. Complete config OWASP ZAP with JSON based authentication to test API

Process test 

> Right Click contexts JsonBaseAuth 

> Active Scan

> Select User: Test1

> Click Start Scan

=> You will see every request call api, that there is the Bearer token and Cookie is stored to authenticate

Thank you.

How to using tool OWASP ZAP to test security

  1. Install and open OWASP (you have to install java before OWASP)
  2. Click Manual Explore | Manual Explore
  3. Setup Protected Mode | Protected Mode
  4. Put URL to explore
  5. Select browser Chrome
  6. Click Launch Browser
    Note: (if there are errors in launch browser then change config brower version in OWASP equal version your Chrom browser)
  7. Input account and login
  8. Select screen need to run
  9. Let OWASP scan your app
  10. Right click domain run
  11. Click Include in Context 
  12. Click on New Context
  13. Click link *
  14. Click OK

    → After include context
  15. Click menu File > Session Properties
  16. Select Authentication
  17. Select [Form-based Authentication]
  18. Click Select
  19. Click domain
  20. Select「POST.login」
  21. Click button Select

    → will show data like below
  22. Update: email={%username%}&password={%password%}
    Username Parameter * is username và Password Parameter * is password
  23. Click Users
  24. Click button Add
  25. Input account cần run
  26. Click Add

    → will show data like below
  27. Click Forced User
  28. Select User created
  29. Click Ok

    → here use is disable
  30. Click to Enable user
  31. Select Active Scan
  32. Select context
  33. Select user

    Select Threshold of SQL Injection to default to scan

click Start Scan

  1. Start Scan
  2. Click Active Scan to see scan process
  3. Click Alert too see erros  
    Red: High
    Dark yellow: Medium
    Light yellow: Low

  1. Click on error to see

    Note: you can off error you dont want

    Click icon to off

Golang Advanced Interview Q&A