Friday, June 17, 2022

Install wireguard on Ubuntu Linux 22.04 LTS

Installing the WireGuard Client

sudo apt update && sudo apt upgrade

sudo apt install openresolv

sudo apt install wireguard


Generating Private and Public Keys

wg genkey | tee private.key | wg pubkey > public.key

sudo nano /etc/wireguard/wg0.conf


In the file type:

[Interface]

PrivateKey = <contents-of-client-privatekey>

Address = 10.0.0.1/24

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

ListenPort = 51820

[Peer]

PublicKey = <contents-of-server-publickey>

AllowedIPs = 10.0.0.2/32


WireGuard Startup

sudo wg-quick up wg0


Check connection status

sudo wg show


Thursday, June 16, 2022

[Dev] Dart 2.17, now you can declare enums with members.

What else can you do with this?

- Define multiple properties

- Add named or positional arguments to the constructor (as long as it's a "const" constructor)

- Define custom methods and getters


Friday, June 10, 2022

[Linux] Install the Nvidia driver and power saving on the dual Nvidia - Intel gpu laptop on Ubuntu

 

The purpose of this tutorial is to install the NVIDIA drivers on Ubuntu Linux on optimus system ( Intel + Nvidia) and switch from a opensource Nouveau driver to the proprietary Nvidia driver. Follow along with our step by step instructions below to install NVIDIA drivers on Ubuntu.

1. Nvidia Graphic Install

Go to Activities >> Software & Updates >> Additional Drivers.

Apply changes and reboot the system post the installation and then validate the driver installation by going again to the Additional Drivers tab. 

2. Install Nvidia Prime

sudo apt-get install nvidia-prime


Then you will have Nvidia X Server Settings in Dash. And there you can find PRIME profiles.

Everytime you wanna switch to Intel vga, just type using this command sudo prime-select intel Switch back to nvidia sudo prime-select nvidia

Tuesday, March 22, 2022

[Dev] Clean and safe code

"As a developer, our primary goal is always to develop an application that works properly, but we should be focused on writing clean and safe code as well. In this section, we will be talking about clean and safe code a lot, so let's look at what we mean by these terms.

Clean code is code that is very easy to read and understand. It is important to write clean code because any code that we write will need to be maintained by someone and that someone is usually the person who wrote it. There is nothing worse than looking back at code you wrote and not being able to understand what it does. It is also a lot easier to find errors in the code that is clean and easy to understand.

By safe code we mean code that is hard to break. There is nothing more frustrating as a developer than to make a small change in our code and have errors pop up throughout the code base or to have numerous bugs pop up within our application. By writing clean code, our code will be inherently safer because other developers will be able to look at the code and understand exactly what it does...."

 - Swift Protocol-Oriented Programming, Jon Hoffman

Wednesday, February 9, 2022

[Dev] OAuth and OpenID Connect

1. Khái niệm

OIDC (OpenID Connect ): một giao thức mở và tin cậy cho phép user xác thực (authenticate) bằng hệ thống bên ngoài ( google, facebook...)

Vd: Đăng nhập hệ thống bằng tài khoản facebook, google

OAuth (Open Authorization): một giao thức cho phép một ứng dụng lấy thông tin của user mà không cần phải biết password của user đó.

Vd:  Sau khi người dùng đã đăng nhập bằng tài khoản facebook, app sẽ lấy được thông tin facebook của user đó. Ở đây việc xác thực thuộc về phía facebook.

Note: Xác thực trước, phân quyền sau

2. OAuth 2.0

2.1 OAuth extension

Oauth bản chất là open framework, được định nghĩa một cách trừu tượng. Ở đây nó chỉ đề ra các tiêu chuẩn, nhưng không nói cụ thể các bước triển khai như thế nào. Vì vậy để áp dụng vào thực tế công việc, người ta phải cài đặt thêm một số tính năng mở rộng để đảm bảo việc truyền tải dễ dàng và an toàn. 

2.2 JWT (JSON Web Token)

Có nhiều loại token nhưng trong OAuth2, ng ta thường sự dụng dạng JWT. Bản chất JWT là 1 container JSON để chứa thông tin user. :)

Thành phần:

  • Header: loại token, thuật toán
  • Payload: chứa thông tin user
  • Signature: chữ ký mã hóa header và payload

Được encode (base64) chứ không encrypt

Các field tiêu chuẩn: iss, iat,aud, exp

More info: https://en.wikipedia.org/wiki/JSON_Web_Token

2.3 OAuth 2 + OIDC

Bản chất OIDC chạy trên nền OAuth2. Nó là một extension để bổ sung tính năng authentication cho OAuth 2. Sử dụng OpenId Connect thì nội dung của access token mà Client sử dụng để request tới Resource Server (BE) sẽ bao gồm cả thông tin user đang grant quyền truy cập tới những resources này.

OAuth2 token:

{

  "access_token": "SlAV32hkKG",

  "token_type": "Bearer",

  "refresh_token": "8xLOxBtZp8",

  "expires_in": 3600,

}

OAuth2 + OIDC token:

{

  "access_token": "SlAV32hkKG",

  "token_type": "Bearer",

  "refresh_token": "8xLOxBtZp8",

  "expires_in": 3600,

  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc

    yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5

    NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ

    fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz

    AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q

    Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ

    NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd

    QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS

    K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4

    XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"

}


3. OAuth 2.0 Framework - RFC 6749

3.1 Thành phần tiêu chuẩn

  • Access token
  • Refresh token
  • Scopes: được lấy những thông tin nào của user 

3.2 OAuth Grant Types

Nói về các phương pháp để lấy token

Có các loại cơ bản sau:

  • Authorization Code Flow
  • PKCE
  • Client Credentials
  • Resource Owner Password
  • Device Code

3.3 Một số endpoint chính

  • /authorize
  • /token
  • /introspect
  • /revoke
  • /info
  • /.well-known/oauth-authorization-server

3.4 ODIC scopes

  • openid: sub
  • profile
  • phone
  • offline_access: trả thêm refresh token

{

  "sub": "35666371",

  "email": "styler@onelogin.com",

  "preferred_username": "Sally",

  "name": "Sally Tyler",

  "at_hash": "znht1pnyrypkT0KdL5HqQQ",

  "rt_hash": "bKEikCYYUi6nXf4GyGnrOA",

  "aud": "78d1d040-20c9-0136-5146-067351775fae92920",

  "exp": 1523664626,

  "iat": 1523657426,

  "iss": "https://openid-connect.onelogin.com/oidc"

}


4. OAuth2 Token

4.1 JWT

  • Header: loại token, thuật toán mã hóa
  • Payload: sub, access token
  • Signature:

4.2 Validity

  • Kiểm tra header
  • Kiểm tra payload
  • Kiểm tra Signature

*Tip: nên sử dụng thư viện để làm việc này

4.3 Access token và Refresh Token

Phải bảo mật refresh token

4.4 Id token

Token JWT chứa profile

Token = Access token + id token

4.5 Các vấn đề về an toàn

  • Lưu trữ dữ liệu cẩn thận
  • Chỉ lấy dữ liệu cần thiết
  • Xóa dữ liệu khi được yêu cầu
  • Nếu token dùng để truy xuất dữ liệu quan trọng thì nên để thời gian hết hạn ngắn.
  • Bảo mật refresh token


5. Grant type: Authorization code

Đổi authorization code để lấy access token.

Có hỗ trợ refresh token

5.1 Flow

1. Client request đến Auth server

2. Client đăng nhập thành công

3. Auth server gửi auth code cho client

4. Client gửi auth code, client id, client secret cho auth server để lấy token

5. Client sử dụng access token này để truy cập


6. Grant type: PKCE (Proof Key for Code Exchange)

Client secret không tham gia quá trình xác thực

6.1 Flow

1. Client tạo code verifier (>43 kí tự)

2. Client tạo code challenge Base64(SHA256(code verifier)))

3. Client gửi code challenge đến Auth server để xác thực

4. Nếu xác thực thành công, Auth server gửi auth code về cho client

5. Client gửi auth code, client id, code verifier cho auth server để lấy token

6. Client sử dụng access token này để truy cập


7. Grant type: Auth code + PKCE

Mạnh nhưng phức tạp

Thay client secret bằng code verifer

7.1 Flow

1. Client tạo code verifier (>43 kí tự)

2. Client tạo code challenge Base64(SHA256(code verifier)))

3. Client request đến Auth server

4. Client đăng nhập thành công

5. Auth server gửi auth code cho client

6. Client gửi auth code, client id, code verifier cho auth server để lấy token

7. Auth server trả về access token

8. Client sử dụng access token này để truy cập


8 Grant type: Implicit

Đã deprecated. Lựa chọn số 2 nếu ko làm đc Auth code flow + PKCE

Không hỗ trợ refresh token

Mobile/ SPA

8.1 Flow

1. Client request đến Auth server

2. Client đăng nhập thành công

3. Auth server callback về 1 url kèm token (Risk)

4. Client sử dụng access token này để truy cập

8.2 Bảo mật

Luôn phải hỗ trợ SSL

Validate token (header, payload, signature)


9. Grant type: Resource Owner Password

Không thể revoke token

9.1 Flow

1. User gửi username/ password cho Auth server

2. Auth server gửi access token cho client

3. Client sử dụng access token này để truy cập

10 Grant type: Client credential flow

10.1 Flow

1. User gửi client id, client secret cho Auth server

2. Auth server gửi access token cho client

3. Client sử dụng access token này để truy cập


11. Grant type: Device grant flow

Đăng nhập trên smart TV, PS4

Thường dùng trên các thiết bị khó nhập liệu bằng cách đăng nhập đại diện qua 1 thiết bị khác

11.1 Flow

1. TV tạo ra 1 device id

2. TV gửi device id đến Auth server

3. Auth server trả về TV verification url kèm client id, device code, 

4. TV định kỳ gửi client id, device code đến Auth server để kiểm tra có token chưa

5. Mobile truy xuất verification url này

6. Mobile thực hiện đăng nhập

7. Auth server lưu token tương ứng với client id và device code

8. TV thực hiện bước 4 và nhận được token

9. TV sử dụng token để đăng nhập


12 Outh Architecture

  • Sử dụng SSL/TLS
  • Validate token (built library)
  • Bảo mật token, refresh token
  • Sử dụng các thư viện uy tín.

12.1 Setup OAuth server bằng Node JS

https://github.com/jaredhanson/oauth2orize

12.2 Setup OAuth server bằng PHP

https://github.com/thephpleague/oauth2-server

13.3 OAuth as a service

OKTA

Grant type choosing path:




Tài liệu tham khảo

https://en.wikipedia.org/wiki/JSON_Web_Token

https://oauth.net/2/

https://www.appsdeveloperblog.com/keycloak-authorization-code-grant-example/

https://www.appsdeveloperblog.com/oauth-device-authorization-grant-flow-example/

https://aaronparecki.com/oauth-2-simplified/

Thư viện

https://www.oauth.com/playground/

https://github.com/openid/AppAuth-iOS


Friday, January 14, 2022

Repository pattern



Repository pattern is a software design pattern that provides an abstraction of data, so that your application can work with a simple abstraction of data layer that has an interface.

Using this pattern can help achieve loose coupling and can keep domain objects persistence ignorant.

It also makes code more testable as it allows us to inject as a dependency a mock repository that implements that defined interface.

Finally, it is a way of centralising the handling of the domain objects.

In Microsat app, this pattern allows me to abstract the domain layer from the data layer and also, inside data layer, the data repository from its data sources (WebAPI, Sqlite, User Defaults, etc.).

Monday, December 13, 2021

iOS: Things I wish I knew before starting iOS development

If you just started learning how to build iOS apps, you might’ve felt overwhelmed by an endless list of things you should know. I’ve been there and I think I’m still there in a way.

Today, I’d like to share with you guys things I wish I had known before getting a foot into the door.

You don’t need to thoroughly understand every single detail about your code.

Because simply put, it’s next to impossible to understand all the moving parts in your code since they’re all tangled with one another, especially if you’re a newbie to Swift.

At the very beginning, it might be more helpful to just accept things as they are. Just follow the tutorial step to make the work done.

And then when you get more comfortable with how it works, you could get further into a low level of how this works.

Language first, framework later

People often first learn the tricks of a framework, and then move on to the language. That’s actually not the right way to go.

The simple reason here is that if you know about the underlying language, it helps you understand how the framework works. If you have no idea about the trades of a a language, there is no way you will understand why something is done a certain way in the framework.

Small Steps Can Make Big Changes

Don’t just read, implement. I’ve often seen developers read through tutorials or sometimes even whole books without anything much to show for it. However, my biggest concern is how much would you retain if you just read ?

Start with an app that you feel most comfortable. And add some function to it day by day. Even a tiny app also has its problem to solve. You wont believe what you would get after time.

Storyboard vs Code

If you’ve read enough articles about the iOS development, I bet you’ve stumbled upon an article about which way is better to create a user interface. In my opinion, you need to learn both of them.

Every company and every developer has their own taste in this matter but I do think you should go with the storyboard if you just start learning it.

It’s more intuitive and easier to see the visual change whenever you do something. And you might not even know what you can do with each UI component yet. Familiarize yourself with all the common components and auto layout enough before moving into creating all in code.

If you get that far with programmatic UI, figure out when one thing is more beneficial and how it’s better than the other. The time will come when you have to create a custom UI in code as if you’re heavily using the storyboard.

Learn about software design patterns

By the time you’re familiar with Swift, it will dawn on you that just making it work is not enough. You need to think about the maintenance aspect of an app, is it relatively easy to add a feature to the code base? is it easy to fix a bug when it’s found? is it easy to unit test?

When you’re working on a big code base and it’s not well-structured, you will find it extremely difficult to make a change or add another feature on top of that. It will get to a point where you made a change but not sure if it had any side effect on somewhere else in the code that leads to another bug.

That’s when design patterns come in the play. It’s all about how we structure code.

Try to learn different design patterns and apply them to your code base for practice. It will give you an insight into what should be considered to make the code base better.

Last but not least, expose yourself to anything related to iOS development

Mastering a technology on your own is great, but sometimes you learn a lot by just looking at the code of others. Be it your colleagues or random tutorials on the internet, try to find why someone approaches a problem in a certain way — and ask questions if necessary.

It’s also important for developers to realize that it’s impossible to know everything, but the knowledge is out there — you just need to Google it. As a beginner, if you’re stuck there is high probability that someone like you had the same problem in the past and the solution is somewhere out there in the internet (this often happens to the veterans too!)

Thank you for your time!