Application - gksrlfw/study GitHub Wiki
Application
Authentication
μΏ ν€
μλ²λ μΏ ν€λ₯Ό μ΄μ©ν΄μ μ μ μ λΈλΌμ°μ μ λ°μ΄ν°λ₯Ό λ£μ μ μμ΅λλ€. μμ²μ΄ λ€μ΄μ€λ©΄ μλ²μμλ μμ²μ λν λ°μ΄ν°μ ν¨κ» λΈλΌμ°μ κ° μ μ₯νμΌλ©΄ νλ λ°μ΄ν°λ₯Ό μΏ ν€μ λ£μ΄μ μλ΅ν©λλ€. λΈλΌμ°μ μ μ μ₯λ μΏ ν€λ μ μ κ° μΉμ¬μ΄νΈμ λ°©λ¬Έν λ λ§λ€ μμ²κ³Ό ν¨κ» 보λ΄μ§κ² λμ΄ μΈμ¦, λ€κ΅μ΄ λ± μ¬λ¬ κΈ°λ₯μ μ 곡ν μ μκ² λ©λλ€.
μΈμ
HTTP μμ²μ stateless λ‘ λͺ¨λ μμ²μ λ 립μ μ λλ€. μΉμλΉμ€κ° 볡μ‘ν μꡬμ¬νμ λ°κ² λλ©΄μ μνλ₯Ό μ μ₯ν μ μλ κΈ°λ₯μ΄ μꡬλμκ³ μ¬κΈ°μ μΈμ μ΄ μ¬μ©λ©λλ€. μ μ κ° λ‘κ·ΈμΈνλ©΄ μλ²λ μΈμ DB μ μ μ μ 보λ₯Ό μ μ₯ν©λλ€. μΈμ ID λ μΏ ν€λ₯Ό ν΅ν΄ λΈλΌμ°μ μ μ μ₯λκ³ , μΉμ¬μ΄νΈμμ μμ²μ 보λΌλλ§λ€ ν¨κ» 보λ΄μ§κ² λκ³ , μλ²λ μΈμ ID λ₯Ό ν΅ν΄ μΈμ DB μ μ μ κ° μλ€λ©΄ μνλ μμ²μ λν μλ΅μ ν΄μ€λλ€. λ°λΌμ λͺ¨λ μ μ μ 보λ μλ²μ μκ²λκ³ , μ μ λ μ€μ§ μΈμ ID λ§ κ°μ΅λλ€.
μ¦, μλ²λ λͺ¨λ μμ²μ λν΄ μΏ ν€μ μλ μΈμ ID λ₯Ό νμΈν΄μΌ νκ³ , μ΄λ μλΉμ€κ° 컀μ§μλ‘ DB μ 걸리λ λΆνκ° μ¦κ°νκ² λ©λλ€. μ΄λ₯Ό ν΄μνκΈ° μν΄ μΈμ DB λ redis κ°μ μΈ λ©λͺ¨λ¦¬ db λ₯Ό μ΄μ©ν©λλ€. (νμΈ νμ.)
ν ν°
μΈμ κ³Ό μΈμ¦ κ³Όμ μ λΉμ·ν©λλ€. νμ¬ μκ°νκ³ μλ μΈμ¦κ³Όμ μ λ€μκ³Ό κ°μ΅λλ€.
-
μ΅μ΄ λ‘κ·ΈμΈ μμ access token, refresh token μ΄ λ°κΈλ©λλ€.
-
access token μ ν΄λΌμ΄μΈνΈμκ², refresh token μ λ³λ μ μ₯μμ μ μ₯λ©λλ€.
(Todo. ν ν°μ νμ·¨κ°λ₯μ± λλ¬Έμ access token μ λ§λ£κΈ°νμ μ§§κ² κ°κ³ refresh token μ μ΄μ©νλ κ²μΌλ‘ μκ³ μμ΅λλ€. refresh token λ ν¨κ» ν΄λΌμ΄μΈνΈλ‘ 보λ΄λ μμλ 보μλλ° λͺ νν μ΄μ κ° μλ νμμΈμ§ νμΈν΄μΌ ν©λλ€. BP κ° νμν©λλ€...)
-
ν΄λΌμ΄μΈνΈμμ λ‘κ·ΈμΈμ΄ νμν κΈ°λ₯μ μμ²νλ κ²½μ° access token μ 보λ λλ€.
-
access token μ΄ μ ν¨νκ³ κΈ°νμ΄ λ§λ£λμμ κ²½μ°μλ§ refresh token μ νμΈν©λλ€. λ§μΌ refresh token μ΄ μμ λμκ±°λ λ§λ£λμλ€λ©΄ λ‘κ·Έμμ μν΅λλ€. μλ κ²½μ°μλ access token μ μ¬λ°κΈ ν΄μ€λλ€.
-
refresh token μ μ ν¨κΈ°νμ νμΈν ν, μΌμ κΈ°κ° μ΄λ΄μ΄λ©΄ μ¬λ°κΈν©λλ€.
(Todo. κ³μν΄μ λ‘κ·ΈμΈμ μ΄μ΄λκ°λ €λ©΄ refresh token λ μ¬λ°κΈμ΄ νμνλ€κ³ μκ°ν©λλ€. μ΄λ μκΈ°μ―€μ refresh token μ μ¬λ°κΈ ν΄μΌνλμ§... BP κ° νμν©λλ€...)
refresh token μ λ§λ£κΈ°νμ΄ μ§λ λκΉμ§ λ‘κ·ΈμΈ μμ²μ΄ λ€μ΄μ€μ§ μμλ€λ©΄ μ λ§λ£κΈ°νμ΄ μ§λλ©΄ (κ·Έλ¦¬κ³ λ‘κ·Έμμ μμλ μμ λ¨) μμ λμ΄μΌ ν©λλ€. redis κ°μ ttl μ΄ μλ DB μ μ μ₯ν μ μμ΅λλ€. access token μ΄ λ§λ£λμμ λλ refresh token μ μ°ΎκΈ° μν΄μ db λ₯Ό νμΈν΄μΌνμ§λ§, λ§€ μμ² μμ DB μ μ κ·Όν΄μΌ νλ μΈμ λ°©μ보λ€λ μ κ·Ό νμκ° μ€μ΄λλλ€.
date & time
νμμ‘΄(timezone) μ΄λ?
νμμ‘΄μ λμΌν λ‘컬 μκ°μ λ°λ₯΄λ μ§μμ μλ―Ένλ©°, ν΄λΉ κ΅κ°μ μν΄ λ²μ μΌλ‘ μ§μ λ©λλ€.
GMT λ λ°λ€μ κΈ°μ , μ°λ§ν΄μ μ’ μ μΌλ‘νλ κ΅μ νμ€μμ λλ€. UTC λ GMT λΌκ³ λ λΆλ¦¬λ©°, μ΄μ μμ«μ λ¨μμμλ§ μ°¨μ΄κ° λκΈ° λλ¬Έμ μΌμμμλ νΌμ©, κΈ°μ μ μΈ νκΈ°μμλ UTC κ° μ¬μ©λ©λλ€.
λνλ―Όκ΅μ UTC+09:00 μ νμ€μΌλ‘ νκ³ , KST λΌκ³ λΆλ¦ λλ€.
νμμ‘΄ μ€μ
μλ² κ°λ°μ ν λ, OS, application server, database μΈκ°μ§μ νμμ‘΄μ λμΌνκ² μ€μ ν΄μΌν©λλ€. μΌλ°μ μΌλ‘ μλ²μ DB μ νμμ‘΄μ OS μ νμμ‘΄μ λ°λΌκ°λλ€.
- OS νμμ‘΄ νμΈ λ° μ€μ
date
timedatectl set-timezone Asia/Seoul
timedatectl set-timezone Etc/UTC
2-1. mysql νμμ‘΄ νμΈ λ° μ€μ (쿼리 μ΄μ©)
SELECT @@GLOBAL.time_zone, @@SESSION.time_zone, @@system_time_zone;
Set global time_zone='Asia/Seoul';
Set time_zone='Asia/Seoul';
Set global time_zone='UTC';
Set time_zone='UTC';
- κΈ°λ³Έμ μΌλ‘ SYSTEM μ΄λΌ νκΈ°λμ΄ μμΌλ©°, μ΄λ OS μ€μ μ λ°λ₯Έλ€λ μλ―Έμ λλ€.
2-2. mysql νμμ‘΄ νμΈ λ° μ€μ (config νμΌ μ΄μ©)
λ¨Όμ my.cnf νμΌ μμΉλ₯Ό νμΈν΄μΌν©λλ€.
mysqld --verbose --help | grep -A 1 'Default options'
config λ₯Ό μΆκ°νκ³ restart λ₯Ό ν΄μ€μΌν©λλ€.
[mysqld]
default-time-zone="+9:00"
- μλ² νμμ‘΄ νμΈ λ° μΈν (Nodejs)
κΈ°λ³Έμ μΌλ‘ nodejs μ Date() κ°μ²΄λ OS μ μκ΄μμ΄ UTC λ₯Ό μ¬μ©ν©λλ€. dayjs λ OS μ νμμ‘΄μ λ°λΌκ°λλ€.
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault('Asia/Seoul');
- mysql λΌμ΄λΈλ¬λ¦¬ νμμ‘΄ μΈν (typeorm)
λΌμ΄λΈλ¬λ¦¬λ¨μμλ νμμ‘΄μ μ€μ ν μ μμ΅λλ€. (https://github.com/mysqljs/mysql)
timezone: The timezone configured on the MySQL server. This is used to type cast server date/time values to JavaScript Date object and vice versa. This can be 'local', 'Z', or an offset in the form +HH:MM or -HH:MM. (Default: 'local')
mysql μ datetime μ νμμ‘΄μ κ°κ³ μμ§ μμ΅λλ€.
μ€μ mysql μλ²λ UTC λ‘ μ€μ λμ΄μμ§λ§ λΌμ΄λΈλ¬λ¦¬μ νμμ‘΄μ KST λ‘ μ€μ ν κ²½μ° λ°μ΄ν°λ KST λ‘ λ³κ²½λμ΄ μ μ₯λλ―λ‘ μΌμΉμμΌμ€μΌν©λλ€.
date & time νκΈ°
ISO 8601
λ μ§μ μκ°μ νκΈ°μ κ΄ν κ΅μ νμ€ κ·κ²©μ λλ€. UTC, timezone κ³Ό ν¨κ» λ¬Έμμ΄ ννλ‘ μκ°μ ννν©λλ€.
ex) 2021-11-06T09:36:22+09:00 : UTC κΈ°μ€μΌλ‘ 9μκ° λ§νΌ λΉ λ¦ λλ€.
ex) 2021-11-06T09:36:22z : UTC κΈ°μ€μλ₯Ό μλ―Έν©λλ€.
ex) 2021-11-06T09:36:22+00:00 : UTC κΈ°μ€μλ₯Ό μλ―Έν©λλ€.
Monkey patching
λͺ½ν€ν¨μΉμ λ°νμ μ€μμ μ€ν μ€μΈ μΈμ€ν΄μ€μλ§ μν₯μ μ€ μ±λ‘ λͺ¨λμ΄λ ν΄λμ€λ₯Ό λ³κ²½νλ νλμ μλ―Έν©λλ€. μΌλ°μ μΌλ‘λ μΆμ²νμ§ μλ λ°©λ²μ΄κ³ , μ€μ μ’ μμ± ν¨ν€μ§μ PR μ 보λ΄κ±°λ μ체 λͺ¨λμ λ§λ€μ΄μ λͺ½ν€ν¨μΉμ νΌν μ μμ΅λλ€.
μλ°μ€ν¬λ¦½νΈμμλ μ£Όλ‘ νλ‘ν νμ μ νΉμ λ©μλλ₯Ό μΆκ°ν λ νΉμ polyfil ν¨μλ₯Ό μμ±ν λ μ¬μ©λ©λλ€.
Array.prototype.last = () => {
return this[this.length - 1];
}
GIS
https://blog.hkwon.me/draw-korean-map-chart-with-geojson/
https://github.com/Seunghyum/SGIS-shpToGeojson
https://www.northrivergeographic.com/loading-data-into-postgis-using-ogr
곡곡λ°μ΄ν° λ€μ΄λ‘λ -> QGIS EUC-KR μΈμ½λ©, μ’νκ³ EPSG:5174 λ‘ λ³κ²½ -> mysql or postgresql
ogr2ogr -f PostgreSQL -t_srs EPSG:4326 PG:"host=localhost user=seohangil dbname=example schemas=example" a2.shp -nln gis2 -skipfailures -lco precision=YES
μ’νκ³ κ²½μλ λ³κ²½
import proj4 from 'proj4';
const exec = (async () => {
//http://openapi.nsdi.go.kr/nsdi/eios/OperationSumryDetail.do
//http://www.gisdeveloper.co.kr/?p=8942
// epsg:5174 EPSG:5174
const a = '+proj=tmerc +lat_0=38 +lon_0=127.0028902777778 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m +no_defs +towgs84=-115.80,474.99,674.11,1.16,-2.31,-1.63,6.43'
const wgs84 = '+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees';
const result = proj4(a, wgs84, [195544.585799999535084, 447909.182499999180436]);
// 198024.045800000429153
// const result = proj4(grs80UtmK, wgs84, [217926.864799999631941, 415204.857499999925494]);
console.log('proj4 result =', result);
})();
μ¬λ
Workspace λ΄μ μ¬λ¬ μ±μ μμ±ν μ μκ³ , μ΄ μ±μ μ΄μ©νμ¬ μ¬λμΌλ‘ λ©μΈμ§λ₯Ό λ³΄λΌ μ μμ΅λλ€.
web api μμ
import { WebAPICallResult, WebClient } from '@slack/web-api';
export class SlackService {
private token = process.env.SLACK_WEB_API_TOKEN;
private web: WebClient;
constructor(private readonly logger: Logger) {
this.web = new WebClient(this.token);
}
postMessage(text: SlackMessage, channel: SlackChannel | string, username: SlackUsername | string): Promise<WebAPICallResult> {
return this.web.chat.postMessage({
text: text.toString(),
asUser: true,
channel,
username,
});
}
}
todo
- gradle, maven, npm
- lombok(https://stackoverflow.com/questions/59136271/is-there-something-like-lombok-for-typescript)
- builer
- κ°λ μ±, κ° μμ± μ μ°, κ°μ²΄ λΆλ³μ±
changeName(name: string) {
return UserCreate.builder().name(name).build();
}
```