Tuesday, August 30, 2022

Basic project planning

Recently, I had followed an online course and I found an interesting brief about how to plan a project. So I decide to put it here just in case someone needs it.

Project planning is one of the most critical stages of software development. It is an important part of commencing any new project. That's because it serves as a roadmap that shows the phases of the project, as well as their start and end dates, and dependencies. By the end of this reading, you should recognize the importance of project planning. 

1. Project performance and success rates

Project planning involves comprehensive mapping and organization of project goals, tasks, schedules and resources before anyone assigns project roles and the team starts implementing the plan. With proper planning in place, you can boost the project performance and success rates of a team.

2. Clear objectives

Having a clear idea of what needs to be achieved greatly increases the likelihood that you will do it. But, without a concise objective from the start, the project will be complicated. If the team isn't clear on what they are working on, it’s almost impossible to know when the project is completed. Proper planning helps the team focus on the most important things: the objectives and the end goal.

3. Resource allocation

Planning out a project will tell you how many team members you need to execute the project. The plan also allows project managers to monitor which resources have been allocated and thus avoid excessive allocation.

4. Communication

Planning helps communication. With good communication, every team member knows exactly what is required of them ahead of time. A well-written plan will help you communicate key details, making it seamless for you and your entire team to complete specific tasks. Listening to their input and ideas is also a great way to achieve buy-in and foster the commitment of every team member.

5. Project-specific training

Project planning ensures team members have the required technical know-how to execute the assigned tasks and identifies talent pipelines to provide an adequate supply of trained talents throughout the lifecycle of the project.

And those are the basics of project planning!

Monday, August 29, 2022

JSON Visio - generates graph diagrams from JSON objects


JSON Visio is a tool that generates graph diagrams from JSON objects. These diagrams are much easier to navigate than the textual format and to make it even more convenient, the tool also allows you to search the nodes. Additionally, the generated diagrams can also be downloaded or clipboard as image.

Check it out: JSON Visio - Directly onto graphs

Sunday, July 24, 2022

How To Secure Flutter Application



1. Stay up-to-date

Getting your flutter sdk, plugin and packages up to date is the easiest and one the best ways to secure your apps. Google Flutter Team releases security fixes and patches for vulnerabilities found on the Flutter framework.


2. Secure your data

Do not use sharing settings or SQLite to store sensitive user data. This is because it is easy to open on any device. So you will be required to encrypt the stored data. For that, you can use flutter_secure_storage. This package uses Keystore for Android and Keychain for iOS


3.Jailbroken and rooted devices

Rooted Android device and jailbroken iOS device have more privileges compared to regular system. It can introduce malwares to the user's device and bypass the normal behavior of the device. There is package in Flutter that is flutter_jailbreak_detection. You can use this package to detect if your app is running on a jailbroken or rooted device. Use Root Beer on Android and DTT Jailbreak Detection on iOS.


4. Local Auth

To prevent unauthorized access we shall use the local_auth package to provide a gateway to get the access the app content as many times the user closes the app temporarily. This includes authentication with biometrics such as fingerprint or facial recognition.


5. Restrict network traffic

One way to restrict network traffic or connection to an unsecured endpoint is through explicity whitelisting your domain


6. Ceritificate pinning

You can also implement certificate pinning for your apps to restrict the secure connection the particular certificates. This ensures that the connection between your apps and your server is trusted and authentic



7. Obfuscate code

The compiled binaries and code of your apps can be reversed engineered. Some of the things that can be exposed include the strings, method and classes, and API keys. These data are either in their original form or in  plain text.

```

flutter build appbundle --obfuscate --split-debug-info=/<directory>

```

Getting Started with Flutter Bloc Pattern

 Bloc Pattern


1. Why Bloc

- Keep your code clarm organized, clean, and maintainable

- Compatible with flutter declarative programming


2. What's Bloc

- A design pattern created by Google to separate Logic from UI 

- There is many library to implement this design pattern. But IMO, you should use the flutter_bloc of Felix Angelo. It is a state management to easier your life

- For every action inside the application, there will be a relative state from it. For example, when the data is fetching, the app should be in a loading state displaying a loading animation on the screen


3. The Core Concepts

- Stream is the foundation of Bloc


3.1 Stream

- Stream is a sequence of async event. Each event is a data event or error event.

- When a stream has dispatched its event, it will also notify to all listener subscribed to it


3.2 Receive Stream

- async* means asynchronous generation function, it generates async data

- yield pushes the data (integer) through the Stream

- await keyword helps to wait for a process to finish before proceeding to the next step


```

Stream<int> dataStream() async* {

for (int i = 0; i<3; i++) {

await Future.delayed(Duration(seconds:3));

yield i;

}

}


Stream<int> stream = dataStream();


stream.listen((event) {

    print("RECEIVE data ${event.toString()}");

  });


```

- async* means asynchronous generation function, it generates async data

- yield pushes the data (integer) through the Stream

- await keyword helps to wait for a process to finish before proceeding to the next step


3.3 Cubit and Bloc


- Cubit is a minimal version of Bloc

- Cubit only emits a stream of states

- Bloc emits a stream of states and receive a stream of event


4. Flutter BLOC

4.1 BlocProvider

- A widget that creates and provides a Bloc to all of its children. A single instance of it can be provided to multi widgets within a tree hierarchy




4.2 Bloc Builder

- BlocBuilder is a widget that helps rebuild the UI based on some Bloc state 

changes

- Rebuild a large UI is a heavy cpu task to compute. That's why you need to wrap the exact part of the UI you want to rebuild inside BlocBuilder. For example, if a text is nested inside a column or a row, dont build entire the column/ row, rather to rebuild the text widge only by wrapping it inside the BlocBuilder

- If you dont provide exactly the cubit/ Bloc in Blocbuilder, it will search for the nearest parent bloc in the tree

5. Code Implementation


counter_app.dart

```

import 'package:flutter/material.dart';


import 'counter/counter.dart';


class CounterApp extends MaterialApp {

  const CounterApp({Key? key}) : super(key: key, home: const CounterPage());

}

```


counter_page.dart

```

import 'package:flutter/material.dart';

import 'package:flutter_bloc/flutter_bloc.dart';


import '../counter.dart';

import 'counter_view.dart';


class CounterPage extends StatelessWidget {

  const CounterPage({Key? key}) : super(key: key);


  @override

  Widget build(BuildContext context) {

    return BlocProvider(

      create: (_) => CounterCubit(),

      child: CounterView(),

    );

  }

}

```


counter_cubit.dart

```

import 'package:bloc/bloc.dart';


class CounterCubit extends Cubit<int> {

  CounterCubit() : super(0);


  /// Add 1 to the current state.

  void increment() => emit(state + 1);


  /// Subtract 1 from the current state.

  void decrement() => emit(state - 1);

}

```


counter_view.dart

```

import 'package:flutter/material.dart';

import 'package:flutter_bloc/flutter_bloc.dart';


import '../counter.dart';


class CounterView extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    final textTheme = Theme.of(context).textTheme;

    return Scaffold(

      appBar: AppBar(title: const Text('Counter')),

      body: Center(

        child: BlocBuilder<CounterCubit, int>(

          builder: (context, state) {

            return Text('$state', style: textTheme.headline2);

          },

        ),

      ),

      floatingActionButton: Column(

        mainAxisAlignment: MainAxisAlignment.end,

        crossAxisAlignment: CrossAxisAlignment.end,

        children: <Widget>[

          FloatingActionButton(

            key: const Key('counterView_increment_floatingActionButton'),

            child: const Icon(Icons.add),

            onPressed: () => context.read<CounterCubit>().increment(),

          ),

          const SizedBox(height: 8),

          FloatingActionButton(

            key: const Key('counterView_decrement_floatingActionButton'),

            child: const Icon(Icons.remove),

            onPressed: () => context.read<CounterCubit>().decrement(),

          ),

        ],

      ),

    );

  }

}

```

6. Summary

- Bloc is a good pattern to improve the code quality and help easier the state management in app

- Must familiar with stream and reactive programming

- Much of boilerplate code


Reference link:

- https://bloclibrary.dev/#/gettingstarted

Thursday, July 21, 2022

How to get your app rejection on App Store (and how to fix it)



App Content Is Inappropriate

  • Apps related to sensitive content, such as porn and gambling, are automatically rejected. They will also not approve content about terrorism, racism, violence, substance abuse. Generally, if your app offends people or encourages them to break the law, you will probably get a rejection approval
  • In this case, either you modify the content or not launch it into the Apple Store.


You Have No Privacy Policy

  • Apple requires the application to take the user privacy data seriously to comply the GDPR in Europe and various FTC rules in the US.
  • To avoid rejection, make sure that users have been aware of the Term Of Use, Privacy Policy.
  • It should explain how you use the specific data that you collect: how it’s stored, and whether or not you share it with other third-party entities.
  • Lastly, the user has full permission for his own data, even asking to remove it: making a function for request to remove data is a reasonable choice. 


Missing Sign in with Apple for third party sign up

  • Apps that exclusively use a third-party or social login service (such as Facebook Login, Google Sign-In, Sign in with Twitter, Sign In with LinkedIn, Login with Amazon, or WeChat Login) to set up or authenticate the user’s primary account with the app must also offer Sign in with Apple as an equivalent option


App Wants to Share Personal User Data

  • In general, users must have control over their data at all times. Users must notice how and why the application would like to use their data and privacy: photos, location, notification...
  • The key is being declaration right and enough permission will avoid you to be rejected in this section.


The App Is a Copy of Another App

  • Apps that are cloned from another app on the Apple Store will get rejection. You should come up with a unique app concept.
  • Another case is spamming, the same app but multiple variants. For example: same app feature and UI but different theme, data...


Hardware and Software Are Not Compatible

  • App can not only run on iPhone but also on iPad as well and vice versa


You’re Using Private API

  • Private APIs are the API used internally by Apple. They are undocumented or  don't officially documented by Apple. The APIs are not stable and can be changed anytime, so they're less guarantee
  • Make sure your code base and even the external libraries don't mess with these or wait for a brutal rejection.


Bugs and Crashes Occur During the Review Process

  • If any crash or significant bug or performance issue (ex: http 500, no network, lagging...) appears during the process, the app will be rejected immediately. Those who perform the review process are human and they test on the physical device (not on an  emulator).
  •  To avoid this, please take the QA step seriously.


Unusually Long Load Times

  • Apps that take long loading times may cause poor user experience, therefore, could be rejected. To prevent this kind of issue, simplify the user interface and optimize your code to make it run faster, compressing images and assets to reduce load times.
  • For apps that need to connect to a server, you only fetch required data and utilize the caching mechanism.
  • For cold startup, it's a good idea to add a splash screen


Placeholder Content Is Still in the App

  • A placeholder or dummy content is a sign of an uncompleted app. A not yet complete app violates the App Store rules, so the app will be rejected.
  • Inspecting every corner of your app ensures that you catch these simple mistakes before submission.


Broken Links in the App

  • Broken links in apps will also be rejected by Apple. For reviewers, it's a sign of poor performance application may affect to user. Thoroughly check all your app links before submit the app.


App Appears to Be Unfinished

  • Even if the app is complete, the mistake in app name (app beta, app dev, app demo...) or build version (0.x) may get your app violate the incomplete app case. The app to submit to stores are considered ready for distribution.
  • Be aware.


Incomplete or Inaccurate Metadata

  • This is about the meta data you put on the App Store Dashboard: app descriptions, screenshots, age ratings, payment options, and privacy information. The key is honest, sincere and transparent. Do not cheat.
  • Remember to upload screenshots for every screen size on the iPhone/ iPad. Do not use any other exotic template device (ex: Android) but an iPhone/iPad.
  • Do not mention any keywords about different platforms (ex: Android)


Low-Quality UI

  • Apple has provided a detailed description of how an app should be designed to comply with their platform (Human Interface Guidelines). 
  • A poor UI design that fails to meet standards may get rejected. 
  • Please make sure your app looks fantastic and consistent across all Apple devices.

Saturday, July 9, 2022

How to prevent wifi sleep after suspend for Ubuntu Linux

 1. Change power state of the wifi card to 3

```

$cat /etc/NetworkManager/conf.d/default-wifi-powersave-on.conf

[connection]

wifi.powersave = 3

# Slow sleep fix: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1670041

#wifi.powersave = 2

```

2. After saving the file run `sudo systemctl restart NetworkManager`

3. Make a reset bash script and name it `iwlwifi-reset`

```

#!/bin/sh


# NAME: /lib/systemd/system-sleep/iwlwifi-reset

# DESC: Resets Intel WiFi which can be flakey after a long suspend.

# DATE: Apr 1, 2017. Modified August 30, 2017.


MYNAME=$0


restart_wifi() {

    /usr/bin/logger $MYNAME 'restart_wifi BEGIN'

    /sbin/modprobe -v -r iwldvm # This removes iwlwifi too

    /sbin/modprobe -v iwlwifi   # This starts iwldvm too

#    systemctl restart NetworkManager.service

    /usr/bin/logger 'systemctl restart NetworkManager.service (SUPPRESSED)'

    /usr/bin/logger $MYNAME 'restart_wifi END'

}

/usr/bin/logger $MYNAME 'case=[' ${1}' ]'

case "${1}/${2}" in

    hibernate|suspend|pre*)

      ;;

    resume|thaw|post*)

      restart_wifi;;

esac

```

4. Copy the iwlwifi-reset script to systemd folder

```

sudo cp -r /path-to-iwlwifi/script /lib/systemd/system-sleep/

```

5. Set excute permission for the script

```

chmod a+x /lib/systemd/system-sleep/iwlwifi-reset

```

Sunday, July 3, 2022

Configure VPN L2TP/IPSec on Ubuntu for Ubuntu Linux


1. sudo apt-get install network-manager-l2tp

2. sudo apt-get install network-manager-l2tp-gnome

3. Settings > Network > Click on "+" > Then choose "Layer 2 Tunneling Protocol (L2TP)"

4. Input VPN name into "Name" textbox.

5. Input host name into "Gateway" textbox.

6. Input user name into "Username" textbox. 

7. Input password into "Username" textbox. 

8. Choose "IPSec Settings".

9. Tick "Enable IPsec tunnel to L2TP host" checkbox

10. Input shared secret into "Pre-shared key". textbox


Bonus:

sudo service xl2tpd stop

sudo systemctl disable xl2tpd

Tuesday, June 28, 2022

Install a custom font on Ubuntu Linux

Install a custom font

sudo mkdir /usr/share/fonts/myfonts && cd /usr/share/fonts/myfonts

sudo unzip -d . ~/Downloads/font.zip

sudo fc-cache -fv

fc-match FontName


Install Microsoft font

sudo apt install ttf-mscorefonts-installer

Font supported list:

  • Times New Roman
  • Arial Black
  • Arial
  • Comic Sans MS
  • Courier New
  • Impact
  • Verdana

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.).