-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrss.xml
4729 lines (4646 loc) · 711 KB
/
rss.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[CTS junior Web developer]]></title><description><![CDATA[Web developer Learning.]]></description><link>https://ctsictai.github.io/</link><generator>GatsbyJS</generator><lastBuildDate>Fri, 31 Jan 2020 14:59:21 GMT</lastBuildDate><item><title><![CDATA[AWS EC2 Setting]]></title><description><![CDATA[AWS EC2 settings]]></description><link>https://ctsictai.github.io//posts/AWS/EC2</link><guid isPermaLink="false">https://ctsictai.github.io//posts/AWS/EC2</guid><pubDate>Invalid Date</pubDate><content:encoded><h1 id="ec2란"><a href="#ec2%EB%9E%80" aria-label="ec2란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EC2란?</h1>
<p>Elastic Compute Cloud의 약자이다.</p>
<p>AWS 상에서 사용하는 Server. EC2 서버에 API를 배포하게 된다.</p>
<p>EC2는 다양한 사양 옵션을 제공한다. t2.nano (CPU 1, 0.5 GB memory) 부터 x1.32xlarge (CPI 128, 1952 GB) 까지 다양하게 제공함으로 필요한 사양의 EC2 인스턴스(instnace)를 선택해서 사용하면 된다 (물론 사양이 좋을 수록 비싸다).</p>
<p>고객들(보통 기업들)의 요구에 따라 다양한 CPU 사양요구를 충족 시키려고 선택할 인스턴스가 계속 늘어나고 있다.</p>
<h1 id="ec2-인스턴스-생성"><a href="#ec2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%83%9D%EC%84%B1" aria-label="ec2 인스턴스 생성 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EC2 인스턴스 생성</h1>
<ol>
<li>Launch instance 선택하고 우분투 서버 선택
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/EC2+1.+setting+computing+select.png"></li>
<li>Instance type을 선택한다. t2<em>micro가 1년 동안 무료임으로 t2</em>micro를 선택한 후 “Next: Configure Instance Details”를 선택한다.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/EC2+2.+instance+selected.png"></p>
<ol start="3">
<li>“Auto-assign Public IP” 설정을 “Enable”로 한다.
나머지는 default 값을 그대로 나두면 된다. 이제 “검토 및 시작”를 클릭하자.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/EC2+3.+instance+detail+setting.png"></p>
<ol start="4">
<li>보안그룹 단계에서 보안그룹을 새로 생성하거나 기존에 세팅해놓은 보안그룹을 선택한다. 여기서는 기존의 보안그룹 선택하는 것으로 하였다.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/EC2+4.+security+group.png"></p>
<ol start="5">
<li>인스턴스 만들기전 최종 세팅 상태를 마지막으로 확인후 “시작하기”를 클릭한다.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/EC2+5.+Instance+Final+review.png"></p>
<ol start="6">
<li>“시작하기”를 누른 뒤 키 페어를 다운로드 받는다. 이 때 이 다운로드 키는 *.pem 형식이며 그 위치를 꼭 기억하도록 하자 이게 없으면 EC2 접속이 안됨!
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/EC2+6.+select+existing+key+pair.png"></li>
<li>EC2 인스턴스 상태 창에서 ‘Public DNS’, ‘Public IP’ 확인한다.
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/EC2+7.+ec2+instance+status.png"></li>
<li>Public IP주소로 ssh 접속을 한다. - EC2 실행</li>
</ol>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">chmod -R 400 *.pem # id/key값만 보기 위한 명령어(pem키가 있는 디렉토리에서 실행해야 한다)
ssh -i path/to/pem(pem키가 있는 경로) [email protected](public Ip 주소)</code></pre></div>
<h1 id="ec2-실행-뒤-세팅background-서버-구동"><a href="#ec2-%EC%8B%A4%ED%96%89-%EB%92%A4-%EC%84%B8%ED%8C%85background-%EC%84%9C%EB%B2%84-%EA%B5%AC%EB%8F%99" aria-label="ec2 실행 뒤 세팅background 서버 구동 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EC2 실행 뒤 세팅(background 서버 구동)</h1>
<ol>
<li>python 3.7 설치
miniconda 설치
conda create -n 가상환경명 env 설치
여기서 깃헙에 올린 프로젝트를 git clone 하고
pip install -r requirements.txt를 통해 pip 설치한다. (가상환경 처음 세팅하는 것과 비슷)</li>
<li>
<p>외부 서버와 연결하여 지속적인 서버 작업이 가능 이 때 그 작업을 백그라운드에서 하기 위해서
gunicorn - back ground process 설정 기능 이거 lib 이용</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">1. nohup</code></pre></div>
<p>background에서 계속 서버가 돌아간다 but 서버를 reboot를 할 경우에는 멈춤
nohup gunicorn myfile:app -b 0.0.0.0:8000 2. daemon<br>
데몬 프로세스로 실행하는 —daemon | —reload는 소스 변경시 재구동</p>
</li>
</ol>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">gunicorn 프로젝트명.wsgi:application --bind=0.0.0.0:8000 --daemon --reload</code></pre></div>
<h2 id="ec2에-docker-container-실행"><a href="#ec2%EC%97%90-docker-container-%EC%8B%A4%ED%96%89" aria-label="ec2에 docker container 실행 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EC2에 Docker container 실행</h2>
<ol>
<li>docker repository에서 pull 받기</li>
</ol>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">(base) ubuntu@ip-172-31-6-119:~$ sudo docker pull ctsictai/wediz:0.1</code></pre></div>
<ol start="2">
<li>container 실행</li>
</ol>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">sudo docker run --name wewantedu(컨테이너 이름) -d -p 8000:8000 ctsictai/wediz:0.1</code></pre></div>
<ul>
<li>d : daemon - background 실행하는 명령어</li>
<li>p : port - 포트매핑</li>
<li>gunicorn porcessing 확인</li>
</ul>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">gunicorn 프로젝트명.wsgi:application --bind=0.0.0.0:8000</code></pre></div>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/gunicorn+wsgi%2Csettings.png"></p></content:encoded></item><item><title><![CDATA[AWS RDS Setting]]></title><description><![CDATA[AWS RDS settings]]></description><link>https://ctsictai.github.io//posts/AWS/RDS</link><guid isPermaLink="false">https://ctsictai.github.io//posts/AWS/RDS</guid><pubDate>Invalid Date</pubDate><content:encoded><h1 id="rds란"><a href="#rds%EB%9E%80" aria-label="rds란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RDS란?</h1>
<p>AWS RDS는 인프라 및 데이터베이스 업데이트를 관리해주는 것 뿐만 아니라 까다로운 관계형 데이터베이스의 설치, 운영 그리고 관리를 지원하는 서비스입니다.</p>
<p>Amazon RDS는 현재 MySQL, Oracle, SQL Server, PostgreSQL, MariaDB, Aurora(MySQL과 호환)을 비롯한 총 6가지 데이터베이스 엔진을 지원하고 있습니다</p>
<h1 id="rds-in-mysql-인스턴스-생성"><a href="#rds-in-mysql-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%83%9D%EC%84%B1" aria-label="rds in mysql 인스턴스 생성 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RDS in MySQL 인스턴스 생성</h1>
<ol>
<li>먼저 MySQL 설정 파일을 만들어야 한다. 직접 안만들어도 default 설정 파일이 있지만 utf-8 인코딩 설정을 해줘야 한국어가 저장 가능하다. 먼저 “Parameters groups” 페이지로 가서 “Create parameter group” 옵션을 선택하자.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/create+parameter+group.png"></p>
<ol start="2">
<li>“Parameter group” 설정 파일을 생성하자. Group name과 Description은 자유롭게 정하면 된다. “Paramter group family”는 생성하는 데이터 베이스와 버전에 맞게 지정해야 한다. 우리의 경우 mysql5.7 데이터베이스를 생성할 예정이니 “mysql5.7”로 하자.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/create+parameter+group+setting+page.png"></p>
<ol start="3">
<li>방금 생성한 설정 파일을 수정 하자.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/create+parameter+group+setting+edit.png"></p>
<ol start="4">
<li>내가 설정할 parameters는 다음과 같다</li>
<li>chracter<em>set</em>client —> utf8mb4로 변경</li>
<li>chracter<em>set</em>connection —> utf8mb4로 변경</li>
<li>chracter<em>set</em>database —> utf8mb4로 변경</li>
<li>chracter<em>set</em>results —> utf8mb4로 변경</li>
<li>chracter<em>set</em>server —> utf8mb4로 변경</li>
<li>collation<em>connection —> utf8mb4</em>general_ci로 변경</li>
<li>collation<em>server —> utf8mb4</em>unicode_ci로 변경</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/create+parameter+group+setting+editing+ex.png"></p>
<p>위의 파라미터를 다 설정 하였으면 “Preview changes”를 눌러서 수정사항 리뷰를 하자. 아래와 같이 나와야 한다.</p>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/create+parameter+group+setting+edit+final+state.png"></p>
<p>모든게 정확하면 “Save Changes”를 클릭</p>
<ol start="5">
<li>“Create database” 클릭 후 MySQL을엔진으로 선택하자.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+1-2.DB%EC%9C%A0%ED%98%95+%EC%84%A0%ED%83%9D.png"></p>
<ol start="6">
<li>데이터 생성방식 선택하자 - 표준 생성으로 선택하고 넘어가면 된다.
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+1-1.DB+%EC%83%9D%EC%84%B1%EB%B0%A9%EC%8B%9D+%EC%84%A0%ED%83%9D+.png"></li>
<li>과금방식 선택
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+2.%EA%B3%BC%EA%B8%88%EC%84%A0%ED%83%9D.png"></li>
<li>DB 세부사항 설정을 하자. 거의 대부분 default 값 그대로 두면 된다. 맨 아래 settings 섹션에서 master username과 비밀번호 그리고 데이테베이스 이름만 설정하면 된다.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+3.%EC%8B%9D%EB%B3%84%EC%9E%90+%EC%9E%90%EA%B2%A9%EC%A6%9D%EB%AA%85.png"></p>
<ol start="9">
<li>인스턴스 클래스 및 스토리지 유형 &#x26; 용량 설정<br>
(1) 인스턴스 클래스 설정
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+4.%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4+%ED%81%AC%EA%B8%B0.png">
(2) 스토리지 유형 및 용량 설정
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+5.%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80+%EC%9C%A0%ED%98%95%EB%B0%8F+%EC%9A%A9%EB%9F%89.png"></li>
<li>VPC 설정</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+6.VPC.png"></p>
<ol start="11">
<li>VPC 추가 연결 설정
<img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/RDS+7.%EC%B6%94%EA%B0%80%EC%97%B0%EA%B2%B0%EC%84%A4%EC%A0%95.png"></li>
</ol>
<p>그리고 Database options 세션에 “DB parameter group”을 방금 생성한 파라미터 설정 파일로 변경해주자. 나머지는 default 값 그대로 하면 된다. 끝나면 “Create database” 버튼을 눌루면 마무리 된다.</p>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/DB+options+parameter+group+(2).png"></p>
<ol start="12">
<li>이제 “Instances” 페이지에 가서 방금 생성한 데이터 베이스 대쉬보드 페이지로 가자. 참고로 데이터 베이스가 사용 준비되기 까지 몇분 이상 소요 될 수 있다.</li>
<li>Security group 설정을 변경하여 어디서든 접속이 가능하게 하자. 원래는 데이터베이스를 이렇게 어디서든 접속 가능하게 열어놓으면 안된다. 해킹의 위험이 있다.</li>
</ol>
<p><img src="https://wedizfundmakerimage.s3.ap-northeast-2.amazonaws.com/security+group.png"></p>
<ol start="14">
<li>생성된 데이터베이스에 접속한후 데이터베이스와 테이블들을 생성하자.</li>
</ol>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">mysql -h database endpoint 주소 입력 -u root -p</code></pre></div>
<p>로그인 해서 local db 생성하듯이 하면 된다.</p></content:encoded></item><item><title><![CDATA[Proxy]]></title><description><![CDATA[Proxy]]></description><link>https://ctsictai.github.io//posts/proxy</link><guid isPermaLink="false">https://ctsictai.github.io//posts/proxy</guid><pubDate>Invalid Date</pubDate><content:encoded><h1 id="proxy"><a href="#proxy" aria-label="proxy permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Proxy</h1>
<p>프록시 서버(proxy server)는 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램을 가리킨다.<br>
서버와 클라이언트 사이에 중계기로서 대리로 통신을 수행하는 것을 가리켜 ‘프록시’, 그 중계 기능을 하는 것을 프록시 서버라고 부른다.</p>
<p>프록시 서버 중 일부는 프록시 서버에 요청된 내용들을 캐시를 이용하여 저장해 둔다. 이렇게 캐시를 해 두고 난 후에, 캐시 안에 있는 정보를 요구하는 요청에 대해서는 원격 서버에 접속하여 데이터를 가져올 필요가 없게 됨으로써 전송 시간을 절약할 수 있게 됨과 동시에 불필요하게 외부와의 연결을 하지 않아도 된다는 장점을 갖게 된다. 또한 외부와의 트래픽을 줄이게 됨으로써 네트워크 병목 현상을 방지하는 효과도 얻을 수 있게 된다</p>
<h1 id="웹-중개자"><a href="#%EC%9B%B9-%EC%A4%91%EA%B0%9C%EC%9E%90" aria-label="웹 중개자 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>웹 중개자</h1>
<p>웹 프락시 서버는 클라이언트의 입장에서 트랜잭션을 수행하는 중개인이다.<br>
HTTP 프락시 서버는 웹 서버이기도 하고 웹 클라이언트이기도 하다.
따라서 직접 프락시를 구축한다면 클라이언트와 서버 양쪽의 규칙을 모두 주의 깊게 따라야 한다.</p>
<ul>
<li>개인 프락시와 공용 프락시<br>
프락시 서버는 하나의 클라이언트가 독점적으로 사용할 수도 있고, 여러 클라이언트가 공유할 수도 있다.
하나의 클라이언트만을 위한 프락시를 개인 프락시, 여러 클라이언트를 위한 프락시를 공용 프락시라 한다.</li>
<li>공용 프락시<br>
대부분의 프락시는 공용이며 공유된 프락시다. 중앙 집중형 프락시를 관리하는게 더 비용효율이 높고 쉽다.<br>
캐시 프락시 서버와 같은 몇몇 프락시 애플리케이션은 프락시를 이용하는 사용자가 많을수록 유리하다.<br>
왜냐하면 여러 사용자들의 공통된 요청에서 이득을 취할 수 있기 때문이다.</li>
<li>개인 프락시<br>
개인 전용 프락시는 흔하지 않지만 꾸준히 사용되고 있다. (클라이언트 컴퓨터에서 직접 실행되는 형태)<br>
브라우저의 기능을 확장하거나 성능 개선, 광고 운영을 위해 작은 프락시를 사용자 컴퓨터에서 직접 실행한다.</li>
</ul>
<h1 id="gateway"><a href="#gateway" aria-label="gateway permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gateway</h1>
<p>서로 다른 네트워크 끼리 통신을 하기 위한 서로 다른 프로토콜을 변환해주는 작업을 하는 곳으로 프랑스인과 한국인이 보통 대화하기 위해서 통역사를 두는 이치와 비슷하다.</p>
<h1 id="프락시-vs-게이트웨이"><a href="#%ED%94%84%EB%9D%BD%EC%8B%9C-vs-%EA%B2%8C%EC%9D%B4%ED%8A%B8%EC%9B%A8%EC%9D%B4" aria-label="프락시 vs 게이트웨이 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>프락시 vs 게이트웨이</h1>
<ul>
<li>프락시는 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결한다.</li>
<li>게이트웨이는 서로 다른 프로토콜을 사용하는 둘 이상을 연결한다.</li>
<li>게이트웨이는 서로 다른 프로토콜로 말하더라도 서로 간의 트랙잭션을 완료할 수 있도록 해주는 변환기처럼 작동한다.</li>
<li>실질적으로는 프락시도 서로 다른 HTTP 버전의 프로토콜 통신을 변환하기 때문에 차이점은 모호하다.</li>
</ul>
<h1 id="router"><a href="#router" aria-label="router permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Router</h1>
<p>라우터는 패킷의 위치를 추출하여, 그 위치에 대한 최적의 경로를 지정하며, 이 경로를 따라 데이터 패킷을 다음 장치로 전향시키는 장치이다. 이때 최적의 경로는 일반적으로는 가장 빠르게 통신이 가능한 경로이므로, 이것이 최단 거리일 수도 있지만, 돌아가는 경로라도 고속의 전송로를 통하여 전달되는 경로가 될 수 있다. 즉, 서로 다른 네트워크 간에 중계 역할을 해주는 장치이다.</p>
<p>라우터의 사용 용도는 서로 다른 네트워크 LAN과 WAN을 연결하는 등의 서로 다른 미디어 타입을 연결할 때 주로 사용되므로, 항상 라우터는 이더넷 인터페이스와 WAN 인터페이스를 기본으로 가지게 되는 것이다. 게이트웨이는 추상적인 개념적으로 네트워크가 외부나 내부로 들어올 수 있는 관문 역할을 하며, 게이트웨이를 구성하기 위해 라우터나 스위치가 필요하다. 그러나 라우터는 게이트웨이 역할을 하는 장비를 지칭하는 것이므로 게이트웨이와 라우터는 비슷하지만 다르다</p></content:encoded></item><item><title><![CDATA[Docker]]></title><description><![CDATA[Docker]]></description><link>https://ctsictai.github.io//posts/Docker</link><guid isPermaLink="false">https://ctsictai.github.io//posts/Docker</guid><pubDate>Mon, 20 Jan 2020 23:30:03 GMT</pubDate><content:encoded><h1 id="docker"><a href="#docker" aria-label="docker permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Docker</h1>
<p>도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다.</p>
<p>컨테이너라 하면 배에 실는 네모난 화물 수송용 박스를 생각할 수 있는데 각각의 컨테이너 안에는 옷, 신발, 전자제품, 술, 과일등 다양한 화물을 넣을 수 있고 규격화되어 컨테이너선이나 트레일러등 다양한 운송수단으로 쉽게 옮길 수 있습니다.</p>
<p>서버에서 이야기하는 컨테이너도 이와 비슷한데 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해줍니다. 백엔드 프로그램, 데이터베이스 서버, 메시지 큐등 어떤 프로그램도 컨테이너로 추상화할 수 있고 조립PC, AWS, Azure, Google cloud등 어디에서든 실행할 수 있습니다.</p>
<p>이 컨테이너를 가장 적극적으로 이용하고 있는 기업이 바로 구글이다. 매주 약 20억개의 컨테이너를 이용 중이라고 한다.</p>
<h1 id="docker-container"><a href="#docker-container" aria-label="docker container permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Docker Container</h1>
<blockquote>
<p>컨테이너는 격리된 공간에서 프로세스가 동작하는 기술입니다.</p>
</blockquote>
<p>가상화 기술의 하나지만 기존방식과는 차이가 있습니다.</p>
<ul>
<li>기존의 가상화 방식은 주로 OS를 가상화하였습니다. (VirtualBox)<br>
비교적 사용법이 간단하지만 무겁고 느려서 운영환경에선 사용할 수 없었습니다.</li>
</ul>
<p>이러한 상황을 개선하기 위해 CPU의 가상화 기술(HVM)을 이용한 KVM(Kernel-based Virtual Machine)과 반가상화 Paravirtualization방식의 Xen이 등장합니다. 이러한 방식은 게스트 OS가 필요하긴 하지만 전체OS를 가상화하는 방식이 아니였기 때문에 호스트형 가상화 방식에 비해 성능이 향상되었습니다. 이러한 기술들은 OpenStack이나 AWS, Rackspace같은 클라우드 서비스에서 가상 컴퓨팅 기술의 기반이 되었습니다.</p>
<p>전가상화든 반가상화든 성능상의 이슈로 인해</p>
<ul>
<li><strong>프로세스를 격리</strong>하는 가상화 기술이 등장!</li>
</ul>
<p>리눅스에서는 이 방식을 리눅스 컨테이너라고 하고 단순히 프로세스를 격리시키기 때문에 가볍고 빠르게 동작합니다. CPU나 메모리는 딱 프로세스가 필요한 만큼만 추가로 사용하고 성능적으로도 거어어어어의 손실이 없습니다.
(우분투 설치)</p>
<p>하나의 서버에 여러개의 컨테이너를 실행하면 서로 영향을 미치지 않고 독립적으로 실행되어 마치 가벼운 VMVirtual Machine을 사용하는 느낌을 줍니다. 실행중인 컨테이너에 접속하여 명령어를 입력할 수 있고 apt-get이나 yum으로 패키지를 설치할 수 있으며 사용자도 추가하고 여러개의 프로세스를 백그라운드로 실행할 수도 있습니다. CPU나 메모리 사용량을 제한할 수 있고 호스트의 특정 포트와 연결하거나 호스트의 특정 디렉토리를 내부 디렉토리인 것처럼 사용할 수도 있습니다.</p>
<p>새로운 컨터이너를 만드는데 걸리는 시간은 겨우 1-2초(체감 0.001초)로 가상머신과 비교도 할 수 없이 빠릅니다.</p>
<p><img src="https://t1.daumcdn.net/cfile/tistory/272F203F5265549F04"></p>
<h1 id="docker-image"><a href="#docker-image" aria-label="docker image permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>DOcker Image</h1>
<blockquote>
<p>이미지는 컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것이다.</p>
</blockquote>
<p>상태값을 가지지 않고 변하지 않습니다(Immutable). 컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장됩니다. 같은 이미지에서 여러개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있습니다.</p>
<p>말그대로 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 더 이상 의존성 파일을 컴파일하고 이것저것 설치할 필요가 없습니다. 이제 새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운받고 컨테이너를 생성만 하면 됩니다. 한 서버에 여러개의 컨테이너를 실행할 수 있고, 수십, 수백, 수천대의 서버도 문제없습니다.</p>
<h2 id="레이어-저장방식"><a href="#%EB%A0%88%EC%9D%B4%EC%96%B4-%EC%A0%80%EC%9E%A5%EB%B0%A9%EC%8B%9D" aria-label="레이어 저장방식 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>레이어 저장방식</h2>
<p>도커 이미지는 Docker hub에 등록하거나 Docker Registry 저장소를 직접 만들어 관리할 수 있습니다. 현재 공개된 도커 이미지는 50만개가 넘고 Docker hub의 이미지 다운로드 수는 80억회에 이릅니다. 누구나 쉽게 이미지를 만들고 배포할 수 있습니다.</p>
<p>컨테이너를 생성할 때도 레이어 방식을 사용하는데 기존의 이미지 레이어 위에 읽기/쓰기read-write 레이어를 추가합니다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용합니다.</p>
<p>가상화의 특성상 이미지 용량이 크고 여러대의 서버에 배포하는걸 감안하면 단순하지만 엄청나게 영리한 설계입니다.</p>
<h1 id="dockerfile"><a href="#dockerfile" aria-label="dockerfile permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dockerfile</h1>
<p>도커는 이미지를 만들기 위해 Dockerfile이라는 파일에 자체 DSLDomain-specific language언어를 이용하여 이미지 생성 과정을 적습니다. 추후에 문법에 대해 자세히 다루겠지만 위 샘플을 보면 그렇게 복잡하지 않다는 걸 알 수 있습니다.</p>
<p>이것은 굉장히 간단하지만 유용한 아이디어인데, 서버에 어떤 프로그램을 설치하려고 이것저것 의존성 패키지를 설치하고 설정파일을 만들었던 경험이 있다면 더 이상 그 과정을 블로깅 하거나 메모장에 적지 말고 Dockerfile로 관리하면 됩니다. 이 파일은 소스와 함께 버전 관리 되고 원한다면 누구나 이미지 생성과정을 보고 수정할 수 있습니다.</p>
<h1 id="docker-hub"><a href="#docker-hub" aria-label="docker hub permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Docker Hub</h1>
<p>github하고 비슷한 기능을 하는 서비스로 도커 이미지를 저장하고 관리하는 서비스이다. 근데 이것이 모두 무료라는 점!!</p></content:encoded></item><item><title><![CDATA[AWS]]></title><description><![CDATA[AWS EC2, RDS, S3]]></description><link>https://ctsictai.github.io//posts/AWS</link><guid isPermaLink="false">https://ctsictai.github.io//posts/AWS</guid><pubDate>Invalid Date</pubDate><content:encoded><h1 id="aws란"><a href="#aws%EB%9E%80" aria-label="aws란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>AWS란?</h1>
<p>AWS는 Amazon Web Service의 줄임말 입니다. AWS는 소위 클라우드 서비스라고도 합니다. 클라우드 서비스는 서버 등의 인프라스트럭쳐를 필요한대로 on demand로 사용할 수 있는 서비스 입니다. 즉, 유저가 직접 서버를 구입하고 설치할 필요 없이 AWS상에서 클릭 몇번으로 서버를 구축하고 사용할 수 있습니다.</p>
<h1 id="ec2-in-aws"><a href="#ec2-in-aws" aria-label="ec2 in aws permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EC2 in AWS</h1>
<p>Elastic Compute Cloud의 약자이다.</p>
<p>AWS 상에서 사용하는 Server. EC2 서버에 API를 배포하게 된다.</p>
<p>EC2는 다양한 사양 옵션을 제공한다. t2.nano (CPU 1, 0.5 GB memory) 부터 x1.32xlarge (CPI 128, 1952 GB) 까지 다양하게 제공함으로 필요한 사양의 EC2 인스턴스(instnace)를 선택해서 사용하면 된다 (물론 사양이 좋을 수록 비싸다).</p>
<p>고객들(보통 기업들)의 요구에 따라 다양한 CPU 사양요구를 충족 시키려고 선택할 인스턴스가 계속 늘어나고 있다.</p>
<h2 id="ec2-특징"><a href="#ec2-%ED%8A%B9%EC%A7%95" aria-label="ec2 특징 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>EC2 특징</h2>
<ul>
<li>컴퓨팅 요구사항의 변화에 따라 컴퓨팅 파워를 조정할 수 있다.</li>
<li>새로운 서버 인스턴스 확보 및 부팅시간을 몇분으로 단축시킬 수 있다.</li>
<li>실제로 사용한 용량만큼만 지불 가능 (요금제 선택에 따라 낭비할 수 도 있음)</li>
<li>Linux / Windows 중 선택 가능하다 (이외 운영체제는 현재 지원하지 않는다)</li>
<li>안정성을 위해 여러 AWS 리전과 가용 영역에 걸쳐 배포.</li>
</ul>
<h1 id="secuirty-group"><a href="#secuirty-group" aria-label="secuirty group permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Secuirty Group</h1>
<p>EC2 인스턴스에 대한 네트워크 트래픽을 제어하는 가상 방화벽 역할을 한다.<br>
즉 security group 설정을 해줘야 EC2 인스턴스에 HTTP와 SSH 접속이 가능하다.</p>
<h1 id="rds"><a href="#rds" aria-label="rds permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RDS</h1>
<p>AWS RDS는 인프라 및 데이터베이스 업데이트를 관리해주는 것 뿐만 아니라 까다로운 관계형 데이터베이스의 설치, 운영 그리고 관리를 지원하는 서비스입니다.</p>
<p>Amazon RDS는 현재 MySQL, Oracle, SQL Server, PostgreSQL, MariaDB, Aurora(MySQL과 호환)을 비롯한 총 6가지 데이터베이스 엔진을 지원하고 있습니다.</p>
<p>데이터베이스의 크기는 기본(m4), 메모리 최적화(r3), 마이크로(t2), 총 3가지 카테고리로 나뉩니다.</p>
<p>최적화 된 I/O을 실현할 수 있도록 각 그룹마다 특성에 맞게 vCPUs, GiBs 메모리, 네트워크 성능 수준이 설정되어 있습니다.</p>
<p>각 RDS 인스턴스에서 “Multi-AZ” 옵션을 설정하면, 다른 가용영역(Availability Zone)에 복제된 데이터베이스를 필요할 때 바로 사용할 수 있습니다.</p>
<p>이는 주로 프로덕션 데이터베이스에 사용됩니다.
한쪽 가용영역에서 장애 및 에러가 발생할 경우, 문제에 영향을 받지 않게 독립된 다른 가용영역에 미리 복제된 데이터베이스를 자동으로 사용해서 복구(Failover)시키는 기능입니다.</p>
<p>이 뿐만 아니라, Amazon은 Aurora라는 자체 데이터베이스를 제공합니다.<br>
이는 장애(fault) 발생에도 더 안전하고 가용영역을 통해 자체 복구가 가능하며 또한 추가적인 퍼포먼스 기능들을 제공합니다.</p>
<h1 id="s3-in-aws"><a href="#s3-in-aws" aria-label="s3 in aws permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>S3 in AWS</h1>
<p>AWS S3(Simple Storage Service)는 이름 그대로 파일을 쉽게 저장할 수 있는 공간을 제공하는 서비스.</p>
<p>Amazon S3에서 제공하는 단순한 웹 서비스 인터페이스를 사용하여 웹에서 언제 어디서나 원하는 양의 데이터를 저장하고 검색할 수 있습니다. 또한 개발자는 Amazon이 자체 웹 사이트의 글로벌 네트워크 운영에 사용하는 것과 같은 높은 확장성과 신뢰성을 갖춘 빠르고 경제적인 데이터 스토리지 인프라에 액세스할 수 있습니다. 이 서비스의 목적은 규모의 이점을 극대화하고 개발자들에게 이러한 이점을 제공하는 것입니다.</p>
<p>파일을 저장 할 수 있을 뿐만이 아니라 파일마다 고유 주소를 부여해주기 때문에 S3에 저장한 파일을 웹상에서 쉽게 읽어들일수 있다.</p>
<p>주로 사이트상의 이미지들을 저장하고 사이트에서 읽어들여 렌더링 해주는데 사용한다.</p>
<h1 id="aws-lambda"><a href="#aws-lambda" aria-label="aws lambda permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>AWS Lambda</h1>
<p>AWS Lambda를 사용하면 서버를 프로비저닝하거나 관리할 필요 없이 코드를 실행할 수 있습니다. 사용한 컴퓨팅 시간에 대해서만 비용을 지불하면 됩니다.</p>
<p>Lambda에서는 사실상 모든 유형의 애플리케이션이나 백엔드 서비스에 대한 코드를 별도의 관리 없이 실행할 수 있습니다. 코드를 업로드하기만 하면, Lambda에서 높은 가용성으로 코드를 실행 및 확장하는 데 필요한 모든 것을 처리합니다. 다른 AWS 서비스에서 코드를 자동으로 트리거하도록 설정하거나 웹 또는 모바일 앱에서 직접 코드를 호출할 수 있습니다.</p>
<h2 id="장점"><a href="#%EC%9E%A5%EC%A0%90" aria-label="장점 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>장점</h2>
<ol>
<li>서버 관리 불필요
서버를 프로비저닝하거나 관리할 필요 없이 AWS Lambda에서 코드를 자동으로 실행합니다. 코드를 작성하고 Lambda에 업로드하기만 하면 됩니다.</li>
<li>지속적 규모 조정
AWS Lambda는 각 트리거에 대한 응답으로 코드를 실행하여 애플리케이션을 자동으로 확장하거나 축소합니다. 코드는 병렬로 실행되고 각 트리거는 개별적으로 처리되어 정확히 워크로드 규모에 맞게 조정됩니다.</li>
<li>밀리초 단위로 측정
AWS Lambda에서는 100밀리초 단위로 코드가 실행되는 시간 및 코드가 트리거되는 회수를 기준으로 요금이 부과됩니다. 사용한 컴퓨팅 시간에 대해서만 비용을 지불하면 됩니다.</li>
<li>일관된 성능
AWS Lambda를 사용하면 기능에 알맞은 메모리 크기를 선택하여 코드 실행 시간을 최적화할 수 있습니다. 또한 프로비저닝된 동시성을 활성화하여 두 자리 수 밀리초로 응답하기 위해 기능을 초기화하고 최적의 준비 상태를 유지할 수 있습니다.</li>
</ol>
<p>AWS 공홈에 나와있는 작동방식 도표입니다.
<img src="https://d1.awsstatic.com/product-marketing/Lambda/Diagrams/product-page-diagram_Lambda-HowItWorks.68a0bcacfcf46fccf04b97f16b686ea44494303f.png"></p></content:encoded></item><item><title><![CDATA[HTTPS]]></title><description><![CDATA[HTTPS and REST]]></description><link>https://ctsictai.github.io//posts/HTTPS</link><guid isPermaLink="false">https://ctsictai.github.io//posts/HTTPS</guid><pubDate>Sun, 19 Jan 2020 23:30:03 GMT</pubDate><content:encoded><h1 id="http란"><a href="#http%EB%9E%80" aria-label="http란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTTP란?</h1>
<p>HyperText Transfer Protocol의 약자로서 클라이언트에서 서버까지의 일련의 흐름을 결정하고 있는 것으로 ‘프로토콜’ 즉 통신 규약이다.</p>
<h2 id="http의-약점"><a href="#http%EC%9D%98-%EC%95%BD%EC%A0%90" aria-label="http의 약점 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTTP의 약점</h2>
<ul>
<li>평문(암호화 하지 않은) 통신이기 때문에 도청이 가능하다.</li>
<li>통신 상대를 확인하지 않기 때문에 위장이 가능하다</li>
<li>완전성을 증명할 수 없기 때문에 변조가 가능하다</li>
</ul>
<h1 id="https는-http의-약점을-보완한-통신규약이다"><a href="#https%EB%8A%94-http%EC%9D%98-%EC%95%BD%EC%A0%90%EC%9D%84-%EB%B3%B4%EC%99%84%ED%95%9C-%ED%86%B5%EC%8B%A0%EA%B7%9C%EC%95%BD%EC%9D%B4%EB%8B%A4" aria-label="https는 http의 약점을 보완한 통신규약이다 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTTPS는 HTTP의 약점을 보완한 통신규약이다</h1>
<p>HTTP에 암호화와 인증과 안전성 보호를 더한 것을 HTTPS(HTTP Secure)라 한다.</p>
<ul>
<li>HTTPS는 웹페지이의 로그인이나 쇼핑의 결제화면 등에서 사용되고 있습니다.</li>
<li>HTTPS를 사용할 경우 <strong>http://</strong>가 아닌 <strong>https://</strong>를 사용합니다.</li>
<li>브라우저에서도 HTTPS가 유효한 웹 사잍트에 액세스할 경우 자물쇠 마크가 표시되는 등 HTTP와 다르게 표시되는 경우가 있습니다.</li>
</ul>
<h2 id="https는-새로운-애플리케이션-계층의-프로토콜이-아닙니다"><a href="#https%EB%8A%94-%EC%83%88%EB%A1%9C%EC%9A%B4-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EA%B3%84%EC%B8%B5%EC%9D%98-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C%EC%9D%B4-%EC%95%84%EB%8B%99%EB%8B%88%EB%8B%A4" aria-label="https는 새로운 애플리케이션 계층의 프로토콜이 아닙니다 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTTPS는 새로운 애플리케이션 계층의 프로토콜이 아닙니다.</h2>
<p>HTTP 통신을 하는 소켓 부분을 SSL(Secure Socket Layer)이나 TLS(Transport Layer SEcurity)이라는 프로토콜로 대체하고 있을 뿐 입니다.</p>
<p>무슨소리냐! HTTPS는 직접 TCP와 통신하지 않고 SSL과 통신을 하게 됩니다.<br>
SSL을 사용함으로써 암호화, 증명서, 완전성 보호를 이용할 수 있게 됩니다.</p>
<h1 id="sslsecure-sockets-layer"><a href="#sslsecure-sockets-layer" aria-label="sslsecure sockets layer permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>SSL(Secure Sockets Layer)?</h1>
<p>클라이언트와 서버간의 통신을 공인된 제3자(CA) 업체가 보증해주는 전자화된 문서</p>
<ul>
<li>HTTP와 독립된 프로토콜입니다.</li>
<li>애플리케이션 계층에서 동작하는 SMTP나 Telnet 등에서도 이용될 수 있습니다.</li>
<li>SSL은 HTTP뿐만 아니라 세계 어느 곳에서도 널리 사용할 수 있는 네트워크 보안기술입니다</li>
</ul>
<h1 id="https는-하이브리드-암호-시스템"><a href="#https%EB%8A%94-%ED%95%98%EC%9D%B4%EB%B8%8C%EB%A6%AC%EB%93%9C-%EC%95%94%ED%98%B8-%EC%8B%9C%EC%8A%A4%ED%85%9C" aria-label="https는 하이브리드 암호 시스템 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTTPS는 하이브리드 암호 시스템</h1>
<p>HTTPS는 공통키 암호와 공개키 암호의 양쪽 성질을 가진 하이브리드 암호 시스템입니다.<br>
두가지 방식을 조합해서 장점을 살립니다.
키를 교환하는 곳에서는 공개키 암호를 사용하고 그 후의 통신에서 메시지를 교환하는 곳에서는 공통키 암호를 사용합니다.</p>
<h2 id="공통키-암호"><a href="#%EA%B3%B5%ED%86%B5%ED%82%A4-%EC%95%94%ED%98%B8" aria-label="공통키 암호 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>공통키 암호</h2>
<p>상호간에 키를 교환하는 암호화 방식을 공개키 암호화 방식이라고 합니다.</p>
<ul>
<li>SSL에서는 공개키 암호화 방식을 채용하고 있습니다.
암호화, 복호화에 하나의 키를 같이 사용하는 방식입니다.</li>
<li>하지만 키를 누군가 손에 넣으면 누구라도 암호를 해독할 수 있는 문제가 있습니다.</li>
</ul>
<h2 id="공개키-암호"><a href="#%EA%B3%B5%EA%B0%9C%ED%82%A4-%EC%95%94%ED%98%B8" aria-label="공개키 암호 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>공개키 암호</h2>
<p>공개키 암호는 공통키 암호의 문제를 해결하기 위해 등장한 방식입니다.</p>
<ul>
<li>공개키 암호에서는 서로 다른 두 개의 키 페어(쌍)를 사용합니다.</li>
<li>비밀키(private key)와 공개키(public key)가 그것입니다.</li>
<li>
<p>비밀키는 알려지면 안되는 키이며, 공개키는 누구에게나 알려져도 괜찮은 키입니다.</p>
<ol>
<li>암호를 보내는 측(클라이언트)이 상대의 공개키를 사용해 암호화를 합니다.</li>
<li>암호화된 정보를 받아들인 상대(서버)는 자신의 비밀키를 사용해 복호화를 실시합니다.</li>
</ol>
</li>
</ul>
<p>이 방식은 암호를 푸는 비밀키를 통신으로 보낼 필요가 없으며 도청에 의해서 키를 빼앗길 걱정이 없습니다.<br>
하지만 공개키가 진짜인지 아닌지를 서버에서 증명할 수가 없습니다.
이 문제를 해결하는 데는 인증기관(CA : Certificate Authority)과 그 기관이 발행하는 공개키 증명서가 이용되고 있습니다.</p>
<h2 id="ca인증기관이란"><a href="#ca%EC%9D%B8%EC%A6%9D%EA%B8%B0%EA%B4%80%EC%9D%B4%EB%9E%80" aria-label="ca인증기관이란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>CA(인증기관)이란?</h2>
<p>인증 기관이란 클라이언트와 서버 모두 신뢰하는 제 3자 기관입니다.</p>
<p>공개키를 인증 기관에 제출하면 인증 기관은 제출된 공개키에 디지털 서명을 하고 서명이 끝난 공개키를 만듭니다.<br>
그리고 공개키 인증서에 서명이 끝난 공개키를 담습니다.<br>
이런 인증 기관의 공개키는 안전하게 클라이언트에 전달되어야 합니다.<br>
하지만 어떤 방법을 사용하더라도 100% 안전이 보장되지 않기 때문에 많은 브라우저가 인증기관의 공개키를 사전에 내장한 상태로 제품을 내놓고 있습니다.</p>
<h2 id="단점"><a href="#%EB%8B%A8%EC%A0%90" aria-label="단점 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>단점</h2>
<p>HTTPS를 사용 시 증명서를 구입하여아 합니다. 증명서의 구입 비용이 부담되는 서비스나 개인 웹사이트의 경우 HTTP만 선택하기도 합니다.
그리고 HTTPS를 사용할 경우 처리가 늦어지게 되는 단점이 있습니다.</p>
<ol>
<li>클라이언트 요청 시, SSL에 필요한 통신이 추가됩니다</li>
<li>암호화 복호화 계산을 하기 때문에 서버나 클라이언트의 리소스를 추가적으로 소비합니다.</li>
</ol>
<p>위와 같은 이유로 항상 HTTPS를 사용하지 않습니다.</p></content:encoded></item><item><title><![CDATA[RESTful API]]></title><description><![CDATA[RESTful API]]></description><link>https://ctsictai.github.io//posts/RESTful</link><guid isPermaLink="false">https://ctsictai.github.io//posts/RESTful</guid><pubDate>Thu, 16 Jan 2020 23:30:03 GMT</pubDate><content:encoded><h1 id="rest란"><a href="#rest%EB%9E%80" aria-label="rest란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST란?</h1>
<p>“Representational State Transfer”의 약자가 REST이다.<br>
자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다. 즉, 자원(resource)의 표현(representation) 에 의한 상태 전달</p>
<ul>
<li>자원은 보통 데이터를 말하며</li>
<li>표현은 자원을 전달하는 방식으로 JSON, XML로 표현된다.</li>
</ul>
<h1 id="rest의-구체적-의미"><a href="#rest%EC%9D%98-%EA%B5%AC%EC%B2%B4%EC%A0%81-%EC%9D%98%EB%AF%B8" aria-label="rest의 구체적 의미 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST의 구체적 의미</h1>
<p>HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.</p>
<ul>
<li>웹 사이트의 이미지, 텍스트, DB 내용 등의 모든 자원에 고유한 ID인 HTTP URI를 부여한다.</li>
</ul>
<h1 id="rest의-장단점"><a href="#rest%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90" aria-label="rest의 장단점 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST의 장단점</h1>
<h2 id="장점"><a href="#%EC%9E%A5%EC%A0%90" aria-label="장점 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>장점</h2>
<ul>
<li>HTTP 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위한 별도의 인프라를 구출할 필요가 없다.</li>
<li>HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.</li>
<li>HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.</li>
<li>Hypermedia API의 기본을 충실히 지키면서 범용성을 보장한다.</li>
<li>REST API 메시지가 의도하는 바를 명확하게 나타내므로 의도하는 바를 쉽게 파악할 수 있다.</li>
<li>여러가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.</li>
<li>서버와 클라이언트의 역할을 명확하게 분리한다.</li>
</ul>
<h2 id="단점"><a href="#%EB%8B%A8%EC%A0%90" aria-label="단점 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>단점</h2>
<ul>
<li>표준이 존재하지 않는다.</li>
<li>사용할 수 있는 메소드가 4가지 밖에 없다.</li>
<li>HTTP Method 형태가 제한적이다.</li>
<li>브라우저를 통해 테스트할 일이 많은 서비스라면 쉽게 고칠 수 있는 URL보다 Header 값이 왠지 더 어렵게 느껴진다.</li>
<li>구형 브라우저가 아직 제대로 지원해주지 못하는 부분이 존재한다.</li>
<li>PUT, DELETE를 사용하지 못하는 점</li>
<li>pushState를 지원하지 않는 점</li>
</ul>
<h1 id="rest가-필요한-이유"><a href="#rest%EA%B0%80-%ED%95%84%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0" aria-label="rest가 필요한 이유 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST가 필요한 이유</h1>
<ol>
<li>애플리케이션 분리 및 통합</li>
<li>다양한 클라이언트의 등장</li>
<li>최근의 서버 프로그램은 다양한 브라우저와 안드로이폰, 아이폰과 같은 모바일 디바이스에서도 통신을 할 수 있어야 한다.<br>
이러한 멀티 플랫폼에 대한 지원을 위해 서비스 자원에 대한 아키텍처를 세우고 이용하는 방법을 모색한 결과, REST에 관심을 가지게 되었다.</li>
</ol>
<h1 id="rest-구성-요소"><a href="#rest-%EA%B5%AC%EC%84%B1-%EC%9A%94%EC%86%8C" aria-label="rest 구성 요소 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST 구성 요소</h1>
<ol>
<li>
<p>리소스</p>
<ul>
<li>모든 자원에 고유한 ID가 존재하고, 이 자원은 Server에 존재한다.</li>
<li>자원을 구별하는 ID는 ‘/groups/:group_id’와 같은 HTTP URI 다.</li>
<li>Client는 URI를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 요청한다.</li>
<li>EX) ”<a href="http://api.lib.com/books/1" target="_blank" rel="nofollow noopener noreferrer">http://api.lib.com/books/1</a>” : 도서관 1번 책 정보</li>
</ul>
</li>
<li>
<p>메소드</p>
<ul>
<li>GET, POST, PUT, DELETE 와 같은 메서드를 제공한다.</li>
</ul>
</li>
<li>
<p>표현(메세지, representation)</p>
<ul>
<li>JSON, XML, TEXT, RSS 등 여러 형태의 Representation으로 나타내어 질 수 있다.</li>
<li>주로 JSON, XML로 많이 표현한다</li>
</ul>
</li>
</ol>
<p>구체적으로 REST를 만들어서 예시를 들어보자</p>
<ul>
<li>“사용자”는 생성되는 리소스 ,</li>
<li>“생성한다” 라는 행위는 메서드</li>
<li>그리고 ‘이름이 Terry인 사용자’는 “메시지”가 된다</li>
</ul>
<p>이를 REST 형태로 표현해보면 HTTP POST, ”<a href="http://myweb/users/1" target="_blank" rel="nofollow noopener noreferrer">http://myweb/users/1</a>”</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">{
&quot;users&quot;:{
&quot;name&quot;:&quot;terry&quot;
}
}</code></pre></div>
<p>JSON 형태로 표현된 리소스(데이터) user의 이름이다.</p>
<h1 id="rest-특징"><a href="#rest-%ED%8A%B9%EC%A7%95" aria-label="rest 특징 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST 특징</h1>
<ol>
<li>
<p>Server-Client(서버-클라이언트 구조)</p>
<ul>
<li>자원이 있는 쪽이 Server, 자원을 요청하는 쪽이 Client가 된다.</li>
<li>REST Server: API를 제공하고 비즈니스 로직 처리 및 저장을 책임진다.</li>
<li>Client: 사용자 인증이나 context(세션, 로그인 정보) 등을 직접 관리하고 책임진다.</li>
<li>서로 간 의존성이 줄어든다.</li>
</ul>
</li>
<li>
<p>Stateless(무상태)</p>
<ul>
<li>HTTP 프로토콜은 Stateless Protocol이므로 REST 역시 무상태성을 갖는다.</li>
<li>Client의 context를 Server에 저장하지 않는다.
즉, 세션과 쿠키와 같은 context 정보를 신경쓰지 않아도 되므로 구현이 단순해진다.</li>
<li>Server는 각각의 요청을 완전히 별개의 것으로 인식하고 처리한다.</li>
<li>각 API 서버는 Client의 요청만을 단순 처리한다.
즉, 이전 요청이 다음 요청의 처리에 연관되어서는 안된다.</li>
<li>물론 이전 요청이 DB를 수정하여 DB에 의해 바뀌는 것은 허용한다.</li>
<li>Server의 처리 방식에 일관성을 부여하고 부담이 줄어들며, 서비스의 자유도가 높아진다.</li>
</ul>
</li>
<li>
<p>Cacheable(캐시 처리 가능)</p>
<ul>
<li>웹 표준 HTTP 프로토콜을 그대로 사용하므로 웹에서 사용하는 기존의 인프라를 그대로 활용할 수 있다.
즉, HTTP가 가진 가장 강력한 특징 중 하나인 캐싱 기능을 적용할 수 있다.</li>
<li>HTTP 프로토콜 표준에서 사용하는 Last-Modified 태그나 E-Tag를 이용하면 캐싱 구현이 가능하다.</li>
<li>대량의 요청을 효율적으로 처리하기 위해 캐시가 요구된다.</li>
<li>캐시 사용을 통해 응답시간이 빨라지고 REST Server 트랜잭션이 발생하지 않기 때문에 전체 응답시간, 성능, 서버의 자원 이용률을 향상시킬 수 있다.</li>
</ul>
</li>
<li>
<p>Layered System(계층화)</p>
<ul>
<li>Client는 REST API Server만 호출한다.</li>
<li>REST Server는 다중 계층으로 구성될 수 있다.</li>
<li>API Server는 순수 비즈니스 로직을 수행하고 그 앞단에 보안, 로드밸런싱, 암호화, 사용자 인증 등을 추가하여 구조상의 유연성을 줄 수 있다.<br>
또한 로드밸런싱, 공유 캐시 등을 통해 확장성과 보안성을 향상시킬 수 있다.</li>
</ul>
</li>
<li>PROXY, 게이트웨이 같은 네트워크 기반의 중간 매체를 사용할 수 있다.</li>
<li>
<p>Code-On-Demand(optional)</p>
<ul>
<li>Server로부터 스크립트를 받아서 Client에서 실행한다.</li>
</ul>
</li>
<li>
<p>Uniform Interface(인터페이스 일관성)</p>
<ul>
<li>URI로 지정한 Resource에 대한 조작을 통일되고 한정적인 인터페이스로 수행한다.</li>
<li>HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.</li>
<li>특정 언어나 기술에 종속되지 않는다.</li>
</ul>
</li>
</ol>
<h1 id="restful-api란"><a href="#restful-api%EB%9E%80" aria-label="restful api란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RESTful API란?</h1>
<ul>
<li>REST 기반으로 서비스 API를 구현한 것</li>
<li>최근 OpenAPI(누구나 사용할 수 있도록 공개된 API: 구글 맵, 공공 데이터 등), 마이크로 서비스(하나의 큰 애플리케이션을 여러 개의 작은 애플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍처) 등을 제공하는 업체 대부분은 REST API를 제공한다.</li>
</ul>
<h1 id="rest-api의-특징"><a href="#rest-api%EC%9D%98-%ED%8A%B9%EC%A7%95" aria-label="rest api의 특징 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST API의 특징</h1>
<ul>
<li>사내 시스템들도 REST 기반으로 시스템을 분산해 확장성과 재사용성을 높여 유지보수 및 운용을 편리하게 할 수 있다.</li>
<li>REST는 HTTP 표준을 기반으로 구현하므로, HTTP를 지원하는 프로그램 언어로 클라이언트, 서버를 구현할 수 있다.
즉, REST API를 제작하면 델파이 클라이언트 뿐 아니라, 자바, C#, 웹 등을 이용해 클라이언트를 제작할 수 있다.</li>
</ul>
<h1 id="rest-api-설계-기본-규칙"><a href="#rest-api-%EC%84%A4%EA%B3%84-%EA%B8%B0%EB%B3%B8-%EA%B7%9C%EC%B9%99" aria-label="rest api 설계 기본 규칙 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>REST API 설계 기본 규칙</h1>
<ol>
<li>
<p>슬래시 구분자(/ )는 계층 관계를 나타내는데 사용한다.</p>
<ul>
<li>Ex) <a href="http://restapi.example.com/houses/apartments" target="_blank" rel="nofollow noopener noreferrer">http://restapi.example.com/houses/apartments</a></li>
</ul>
</li>
<li>
<p>URI 마지막 문자로 슬래시(/ )를 포함하지 않는다.</p>
<ul>
<li>URI에 포함되는 모든 글자는 리소스의 유일한 식별자로 사용되어야 하며 URI가 다르다는 것은 리소스가 다르다는 것이고, 역으로 리소스가 다르면 URI도 달라져야 한다.</li>
<li>REST API는 분명한 URI를 만들어 통신을 해야 하기 때문에 혼동을 주지 않도록 URI 경로의 마지막에는 슬래시(/)를 사용하지 않는다.</li>
<li>Ex) <a href="http://restapi.example.com/houses/apartments/" target="_blank" rel="nofollow noopener noreferrer">http://restapi.example.com/houses/apartments/</a> (X)</li>
</ul>
</li>
<li>
<p>하이픈(- )은 URI 가독성을 높이는데 사용</p>
<ul>
<li>불가피하게 긴 URI경로를 사용하게 된다면 하이픈을 사용해 가독성을 높인다.</li>
</ul>
</li>
<li>밑줄(_ )은 URI에 사용하지 않는다.</li>
<li>URI 경로에는 소문자가 적합하다.</li>
<li>RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정하기 때문</li>
<li>
<p>파일확장자는 URI에 포함하지 않는다.</p>
<ul>
<li>REST API에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않는다.</li>
<li>Accept header를 사용한다.</li>
<li>Ex) <a href="http://restapi.example.com/members/soccer/345/photo.jpg" target="_blank" rel="nofollow noopener noreferrer">http://restapi.example.com/members/soccer/345/photo.jpg</a> (X)</li>
<li>Ex) GET / members/soccer/345/photo HTTP/1.1 Host: restapi.example.com Accept: image/jpg (O)</li>
</ul>
</li>
<li>
<p>리소스 간에는 연관 관계가 있는 경우</p>
<ul>
<li>/리소스명/리소스 ID/관계가 있는 다른 리소스명</li>
<li>Ex) GET : /users/{userid}/devices (일반적으로 소유 ‘has’의 관계를 표현할 때)</li>
</ul>
</li>
</ol>
<p><img src="https://gmlwjd9405.github.io/images/network/rest.png"></p></content:encoded></item><item><title><![CDATA[OAuth2.0]]></title><description><![CDATA[OAuth2.0]]></description><link>https://ctsictai.github.io//posts/OAuth</link><guid isPermaLink="false">https://ctsictai.github.io//posts/OAuth</guid><pubDate>Tue, 14 Jan 2020 23:30:03 GMT</pubDate><content:encoded><h1 id="oauth-개념"><a href="#oauth-%EA%B0%9C%EB%85%90" aria-label="oauth 개념 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>OAuth 개념</h1>
<p>OAuth 2.0은 외부 서비스(third-party application)의 인증 및 권한부여를 관리하는 범용 프레임워크 입니다.</p>
<p>OAuth 기반 서비스의 API를 호출을 할 때에는, HTTP 헤더에 access token을 포함하여 요청을 보내게 됩니다. 서비스는 access token을 검사하면서 이 요청이 유효한지 판단하여 적절한 결과를 응답합니다.</p>
<p>사용자 입장에선 OAuth의 권한 요청 절차는 access token을 획득하는 것이 가장 주요한 목적이라 할 수 있고, 서비스 제공자 입장에선 인증된 사용자에게 access token을 발급하는 것이 가장 중요한 일이라 할 수 있습니다.</p>
<p>결국 소셜 로그인 API를 만들기 위한 과정이다.</p>
<p>여기서 중요한 것은 소셜 로그인 기능을 넣더라도 결국은 세션/쿠키 방식이나 토큰을 활용해 인증을 거쳐야 한다는 것이다.</p>
<h2 id="oauth에서-중요한-용어들"><a href="#oauth%EC%97%90%EC%84%9C-%EC%A4%91%EC%9A%94%ED%95%9C-%EC%9A%A9%EC%96%B4%EB%93%A4" aria-label="oauth에서 중요한 용어들 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>OAuth에서 중요한 용어들</h2>
<ul>
<li>Resource Owner : User, 즉 일반 사용자를 칭합니다.</li>
<li>
<p>Client : 우리가 관리하는 어플리케이션 서버</p>
<ul>
<li>User와 혼동될 수 있는데 아니다!!! - 헷갈리지말자</li>
<li>프론트 서버와 백엔드 서버 둘 다 포함하는 개념이다.</li>
</ul>
</li>
<li>Authorization Server : 권한을 관리하는 서버입니다. Access Token, Refresh Token을 발급, 재발급 해주는 역할을 합니다.(프론트에서 받은 토큰 발급 프로세스를 진행하는 곳)</li>
<li>Resource Server : OAuth2.0을 관리하는 서버(Google, Facebook, Naver 등) 의 자원을 관리하는 서버입니다. 주의할 점은 우리가 만드는 서버의 자원을 관리하는 곳이 아닙니다. Oauth 2.0 관리 서버의 자체 API를 의미합니다.</li>
<li>
<p>Authorization Code : 권한 서버에서 인증을 받아 권한을 받아 Token 발급 받을 때 중간과정으로 권한 코드를 받아 클라이언트(우리가 관리하는 서버)에 보내고 클라이언트가 이걸 권한 서버에 보내서 Token을 받는다. (한번 더 보안벽이 있다고 이해하였다.)</p>
<ul>
<li>facebook, google 등에서 사용되는 방법이다.</li>
</ul>
</li>
</ul>
<p><img src="https://t1.daumcdn.net/cfile/tistory/9945F13F5B6EECC02A"></p>
<ol>
<li>Resource Owner(사용자)가 Client(우리 서버)에게 인증 요청을 합니다.</li>
<li>Client는 Authorization Request를 통해 Resource Owner에게 인증할 수단(ex Facebook, Google 로그인 url)을 보냅니다.</li>
<li>Resource Owner는 해당 Request를 통해 인증을 진행하고 인증을 완료했다는 신호로 Authorization Grant를 url에 실어 Client에게 보냅니다.</li>
<li>Client는 해당 권한증서(Authorization Grant)를 Authorization Server에 보냅니다.</li>
<li>Authorization Server는 권한증서를 확인 후, 유저가 맞다면 Client에게 Access Token, Refresh Token, 그리고 유저의 프로필 정보(id 포함) 등을 발급해줍니다.</li>
<li>Client는 해당 Access Token을 DB에 저장하거나 Resource Owner에게 넘깁니다.</li>
<li>Resource Owner(사용자)가 Resource Server에 자원이 필요하면, Client는 Access Token을 담아 Resource Server에 요청합니다.</li>
<li>Resource Server는 Access Token이 유효한지 확인 후, Client에게 자원을 보냅니다.</li>
<li>만일 Access Token이 만료됐거나 위조되었다면, Client는 Authorization Server에 Refresh Token을 보내 Access Token을 재발급 받습니다.</li>
<li>그 후 다시 Resource Server에 자원을 요청합니다.</li>
<li>만일 Refresh token도 만료되었을 경우, Resource Owner는 새로운 Authorization Grant를 Client에게 넘겨야합니다. (이는 다시 사용자가 다시 로그인 하라는 말입니다.)</li>
</ol></content:encoded></item><item><title><![CDATA[transaction]]></title><description><![CDATA[Transaction]]></description><link>https://ctsictai.github.io//posts/django/transaction</link><guid isPermaLink="false">https://ctsictai.github.io//posts/django/transaction</guid><pubDate>Tue, 14 Jan 2020 23:30:03 GMT</pubDate><content:encoded><h1 id="트랜잭션이란"><a href="#%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EC%9D%B4%EB%9E%80" aria-label="트랜잭션이란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>트랜잭션이란?</h1>
<p>트랜잭션(Transaction)은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미한다.</p>
<p>트랜잭션의 특징</p>
<ol>
<li>트랜잭션은 데이터베이스 시스템에서 병행 제어 및 회복 작업 시 처리되는 작업의 논리적 단위이다.</li>
<li>사용자가 시스템에 대한 서비스 요구 시 시스템이 응답하기 위한 상태 변환 과정의 작업단위이다.</li>
<li>하나의 트랜잭션은 Commit되거나 Rollback된다.</li>
</ol>
<h2 id="acidatomicity-consistency-isolation-durability"><a href="#acidatomicity-consistency-isolation-durability" aria-label="acidatomicity consistency isolation durability permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ACID(Atomicity, Consistency, Isolation, Durability)</h2>
<p>트랜잭션에 있어서 중요한 4가지 특징이다. 꼭 알아둬야 되는 개념으로 한 번 정리하고 넘어간다.</p>
<ol>
<li><strong>원자성(Atomicity)</strong>은 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다.<br>
예를 들어, 자금 이체는 성공할 수도 실패할 수도 있지만 보내는 쪽에서 돈을 빼 오는 작업만 성공하고 받는 쪽에 돈을 넣는 작업을 실패해서는 안된다. 원자성은 이와 같이 중간 단계까지 실행되고 실패하는 일이 없도록 하는 것이다.</li>
<li><strong>일관성(Consistency)</strong>은 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미한다.<br>
무결성 제약이 모든 계좌는 잔고가 있어야 한다면 이를 위반하는 트랜잭션은 중단된다.</li>
<li><strong>고립성(Isolation)</strong>은 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다.<br>
이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다. 은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다.<br>
공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미한다. 성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다.</li>
<li><strong>지속성(Durability)</strong>은 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다.<br>
시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다. 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다.<br>
트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.</li>
</ol>
<h1 id="트랜잭션-연산-및-상태"><a href="#%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%97%B0%EC%82%B0-%EB%B0%8F-%EC%83%81%ED%83%9C" aria-label="트랜잭션 연산 및 상태 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>트랜잭션 연산 및 상태</h1>
<h3 id="commit연산"><a href="#commit%EC%97%B0%EC%82%B0" aria-label="commit연산 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Commit연산</h3>
<ul>
<li>COMMIT은 변경한 데이터를 데이터베이스에 마지막으로 반영하고 현재의 트랜잭션을 종료하라는 명령어</li>
<li>COMMIT을 하면 트랜잭션의 처리과정이 모두 반영되며 하나의 트랜잭션 과정이 끝남</li>
<li>COMMIT하기 전 데이터가 저장됨</li>
<li>DDL(CREATE, DROP, ALTER, RENAME, TRUNCATE)은 AutoCommit임</li>
<li>정상적인 종료시에도 COMMIT 작업을 수행함 (EXIT로 종료)</li>
</ul>
<h3 id="rollback연산"><a href="#rollback%EC%97%B0%EC%82%B0" aria-label="rollback연산 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Rollback연산</h3>
<ul>
<li>ROLLBACK은 그 반대로 변경한 데이터를 변경(DML)을 취소하고 현재의 트랜잭션을 끝내라는 명령어</li>
<li>트랜잭션으로 인한 하나의 묶음처리가 시작되기 이전의 상태로 되돌려지는 것</li>
<li>이전 COMMIT한 곳까지만 복구가 됨</li>
<li>이전의 상태로 돌아가니 지금까지 수행했던 데이터베이스의 변경을 모두 무효화시킴</li>
<li>비정상적인 종료시 자동으로 ROLLBACK 작업을 수행함 (우측 상단 X버튼 클릭시, 정전, 컴퓨터가 Down시)</li>
</ul>
<h3 id="트랜잭션-상태도"><a href="#%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%83%81%ED%83%9C%EB%8F%84" aria-label="트랜잭션 상태도 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>트랜잭션 상태도</h3>
<p><img src="https://t1.daumcdn.net/cfile/tistory/997656365AE1FCA40B"></p>
<h1 id="transaction-in-django"><a href="#transaction-in-django" aria-label="transaction in django permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Transaction in Django</h1>
<h2 id="데코레이터decorator를-이용한-python--django-트랜잭션"><a href="#%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0decorator%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-python--django-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98" aria-label="데코레이터decorator를 이용한 python django 트랜잭션 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>데코레이터(decorator)를 이용한 python + django 트랜잭션</h2>
<p>django 에서 트랜잭션을 이용하는 가장 쉬운 방법으로 데코레이터를 이용하는 방법입니다. 데코레이터를 이용하게 되면, 메서드 안에는 코드를 삽입할 필요가 없습니다.<br>
<strong>“@transaction.atomic”</strong> 이라는 데코레이터를 붙여주기만 하면 끝입니다. django 에서 기본적으로 제공해주는 데코레이터이므로, 따로 모듈을 설치해줄 필요도 없습니다.<br>
가장 간단하게 atomic(원자성)한 트랜잭션을 처리하기 위한 손쉬운 방법이죠</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">from django.db import transaction # 장고에서 제공하는 transaction
@transaction.atomic # transaction decorator
def transaction_test1(arg1, arg2):
# start transaction
a.save()
b.save()
# end transaction</code></pre></div>
<h2 id="with-명령어를-이용한-트랜잭션"><a href="#with-%EB%AA%85%EB%A0%B9%EC%96%B4%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98" aria-label="with 명령어를 이용한 트랜잭션 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>with 명령어를 이용한 트랜잭션</h2>
<p>메서드 전체가 아닌 메서드의 일부분만 트랜잭션으로 묶어줄 필요가 있을 때 사용합니다. 트랜잭션으로 묶일 부분을 직접 지정해줘야 하는 불편함(?)이 있지만, 데코레이터와 마찬가지로 비교적 간단하게 처리가 가능합니다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">from django.db import transaction
def transaction_test2(arg1, arg2):
a.save() # 항상 save 처리됨, 예외가 발생할 경우 에러 발생
with transaction.atomic(): # 메서드에 일부분만 트랜잭션 처리
# start transaction
b.save()
c.save()
# end transaction</code></pre></div>
<h2 id="savepoint-를-직접-지정해-주는-트랜잭션"><a href="#savepoint-%EB%A5%BC-%EC%A7%81%EC%A0%91-%EC%A7%80%EC%A0%95%ED%95%B4-%EC%A3%BC%EB%8A%94-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98" aria-label="savepoint 를 직접 지정해 주는 트랜잭션 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>savepoint 를 직접 지정해 주는 트랜잭션</h2>
<p>위의 2가지 방법의 경우, 메서드 내에서(트랜잭션으로 묶여져있는) exception 이 발생하더라도 저절로 롤백이 되기 때문에 예외처리를 따로 해 줄 필요는 없습니다.<br>
하지만, 3 번의 경우에는 savepoint 및 cummit 지점을 직접 지정해 주기 때문에 <strong>예외처리</strong> 또한 별도로 처리되어야 합니다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">from django.db import transaction
def transaction_test3(arg1, arg2):
a.save()
sid = transaction.savepoint()
# start transaction
try:
b.save()
c.save()
transaction.savepoint_commit(sid)
# end transaction
except Exception
# 트랜잭션 내에서 에러 발생시 롤백처리
transaction.savepoint_rollback(sid)</code></pre></div>
<h2 id="db-설정에서-트랜잭션-처리를-자동으로-설정하는-방법"><a href="#db-%EC%84%A4%EC%A0%95%EC%97%90%EC%84%9C-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%B2%98%EB%A6%AC%EB%A5%BC-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%84%A4%EC%A0%95%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95" aria-label="db 설정에서 트랜잭션 처리를 자동으로 설정하는 방법 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>DB 설정에서 트랜잭션 처리를 자동으로 설정하는 방법</h2>
<p>django의 기본 프로젝트 디렉토리에 settings.py에 있는 DATABASE 설정에서 주요 문구를 추가하면된다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"># settings/base.py
DATABASE = {
&#39;default&#39;: {
#...생략
&#39;ATOMIC_REQUESTS&#39;: True,
}
}</code></pre></div>
<ul>
<li>‘ATOMIC_REQUESTS’: False, 라면 디폴트값이 트랜잭션 처리를 하지 않는다. 그래서 데이터베이스 변화가 있는 API를 설계할 때 일일히 지정해줘야 한다.</li>
</ul></content:encoded></item><item><title><![CDATA[Bcrypt]]></title><description><![CDATA[Bcrypt encryption of security information]]></description><link>https://ctsictai.github.io//posts/django/bcrypt</link><guid isPermaLink="false">https://ctsictai.github.io//posts/django/bcrypt</guid><pubDate>Mon, 13 Jan 2020 23:30:03 GMT</pubDate><content:encoded><h1 id="bcrypt란"><a href="#bcrypt%EB%9E%80" aria-label="bcrypt란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bcrypt란?</h1>
<p>Blowfish를 기반으로 만들어진 “단방향 암호화 해싱함수”로 1999년 USENIX에서 발표됐다. Rainbow table 공격을 막기 위해서 salt를 사용하며, 암호검사 요청이 반복될 수록 cost를 늘림으로써, 무차별 대입 공격(brute-force search)을 막을 수 있다. cost는 반복횟수로 2^n 이다.</p>
<ul>
<li>Rainbow table attack이란?
미리 해쉬값들을 계산해 놓은 테이블을 Rainbow table이라고 한다. 이것으로 암호화된 해쉬값을 풀어내는 것</li>
</ul>
<h2 id="bcrypt-암호화-적용-구조"><a href="#bcrypt-%EC%95%94%ED%98%B8%ED%99%94-%EC%A0%81%EC%9A%A9-%EA%B5%AC%EC%A1%B0" aria-label="bcrypt 암호화 적용 구조 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bcrypt 암호화 적용 구조</h2>
<p><img src="https://docs.google.com/drawings/d/e/2PACX-1vQNx1HRk87QQFoenXuRby493jI2Eg6gXIlTN-sxLFfurB-5FI5I5lutbrO-OPqWdnln2PBWXJv2X2Kl/pub?w=860&#x26;h=168"></p>
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>:</mo><mi>b</mi><mi>c</mi><mi>r</mi><mi>y</mi><mi>p</mi><mi>t</mi><mtext>의오리지날버전은</mtext></mrow><annotation encoding="application/x-tex">: bcrypt의 오리지날 버전은</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">b</span><span class="mord mathdefault">c</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="mord mathdefault">p</span><span class="mord mathdefault">t</span><span class="mord hangul_fallback">의</span><span class="mord hangul_fallback">오</span><span class="mord hangul_fallback">리</span><span class="mord hangul_fallback">지</span><span class="mord hangul_fallback">날</span><span class="mord hangul_fallback">버</span><span class="mord hangul_fallback">전</span><span class="mord hangul_fallback">은</span></span></span></span>2a<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>:</mo><mi>b</mi><mi>c</mi><mi>r</mi><mi>y</mi><mi>p</mi><mi>t</mi><mtext>의오리지날버전은</mtext></mrow><annotation encoding="application/x-tex">: bcrypt의 오리지날 버전은</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">b</span><span class="mord mathdefault">c</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="mord mathdefault">p</span><span class="mord mathdefault">t</span><span class="mord hangul_fallback">의</span><span class="mord hangul_fallback">오</span><span class="mord hangul_fallback">리</span><span class="mord hangul_fallback">지</span><span class="mord hangul_fallback">날</span><span class="mord hangul_fallback">버</span><span class="mord hangul_fallback">전</span><span class="mord hangul_fallback">은</span></span></span></span>2<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>다</mtext><mi mathvariant="normal">.</mi><mtext>오리지날버전은</mtext><mi>n</mi><mi>o</mi><mi>n</mi><mo>−</mo><mi>A</mi><mi>S</mi><mi>C</mi><mi>I</mi><mi>I</mi><mtext>문자나</mtext><mi>N</mi><mi>u</mi><mi>l</mi><mi>l</mi><mtext>문자를처리하는방법을정의하지않았다</mtext><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">다. 오리지날 버전은 non-ASCII 문자나 Null 문자를 처리하는 방법을 정의하지 않았다.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord hangul_fallback">다</span><span class="mord">.</span><span class="mord hangul_fallback">오</span><span class="mord hangul_fallback">리</span><span class="mord hangul_fallback">지</span><span class="mord hangul_fallback">날</span><span class="mord hangul_fallback">버</span><span class="mord hangul_fallback">전</span><span class="mord hangul_fallback">은</span><span class="mord mathdefault">n</span><span class="mord mathdefault">o</span><span class="mord mathdefault">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathdefault">A</span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="mord mathdefault" style="margin-right:0.07847em;">I</span><span class="mord mathdefault" style="margin-right:0.07847em;">I</span><span class="mord hangul_fallback">문</span><span class="mord hangul_fallback">자</span><span class="mord hangul_fallback">나</span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span><span class="mord mathdefault">u</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord hangul_fallback">문</span><span class="mord hangul_fallback">자</span><span class="mord hangul_fallback">를</span><span class="mord hangul_fallback">처</span><span class="mord hangul_fallback">리</span><span class="mord hangul_fallback">하</span><span class="mord hangul_fallback">는</span><span class="mord hangul_fallback">방</span><span class="mord hangul_fallback">법</span><span class="mord hangul_fallback">을</span><span class="mord hangul_fallback">정</span><span class="mord hangul_fallback">의</span><span class="mord hangul_fallback">하</span><span class="mord hangul_fallback">지</span><span class="mord hangul_fallback">않</span><span class="mord hangul_fallback">았</span><span class="mord hangul_fallback">다</span><span class="mord">.</span></span></span></span>2a$는 널 문자를 포함하며, UTF-8로 인코딩 할 것을 정의한 버전이다. (encoding=‘utf-8’)</li>
<li>10$ : Cost의 크기는 2^10이다. Iteration count를 1024만큼 돌리겠다는 얘기다. (bcrypt.gensalt(round=10))</li>
<li>N9qo8uLOickgx2ZMRZoMye : 랜덤하게 만든 salt</li>
<li>ljZAgcFl7p92ldGxad68LJZdL17lhWy : 패스워드. Salt와 패스워드를 묶어서 해시해버렸기 때문에, 유추가 불가능하다.</li>
</ul>
<p><img src="http://d2.naver.com/content/images/2015/06/helloworld-318732-2.png"></p>
<h1 id="django에서-사용하기"><a href="#django%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0" aria-label="django에서 사용하기 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Django에서 사용하기</h1>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">import bcrypt # 임포트한다(그 전에 라이브러리 설치는 필수)</code></pre></div>
<h2 id="main-processsignup"><a href="#main-processsignup" aria-label="main processsignup permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Main process(signup)</h2>
<p>bytes(user_data, encoding=‘utf-8’) → bcrypt.hashpw(data, bcrypt.gensalt()) -> .decode(‘utf-8’)</p>
<ul>
<li>bytes(암호화할 패스워드, encoding=‘utf-8’한글포함한 대부분의 문자 포함)화 한다</li>
<li>bcrypt.hashpw(암호화할 패스워드, 솔트 추가) - 암호화 함수</li>
<li>bcrypt.gensalt() -보안강화를 위한 salt 추가!</li>
<li>.decode(‘utf-8’) - type을 ‘str’으로 변환</li>
</ul>
<h1 id="signin-process"><a href="#signin-process" aria-label="signin process permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Signin Process</h1>
<p>password 값 도착 → bcrypt.hashpw(받은password, bcrypt.gensalt()) → DB password encoding→ checkpw(받은 패스워드 인코딩한 값, DB에 저장된 password 인코딩한 값) 비교</p>
<ul>
<li>프론트에서 입력한 password를 요청 받음</li>
<li>받은 password 암호화</li>
<li>DB password 불러와서 encoding한다. (type 맞춰주기 위해서)</li>
<li>bcrypt.checkpw(받은 패스워드 인코딩한 값, DB에 저장된 password 인코딩한 값) 비교 함수 적용</li>
<li>일치하면 로그인 성공</li>
<li>일치하지 않으면 로그인 실패</li>
</ul>
<h2 id="추가로-쓰이는-인자"><a href="#%EC%B6%94%EA%B0%80%EB%A1%9C-%EC%93%B0%EC%9D%B4%EB%8A%94-%EC%9D%B8%EC%9E%90" aria-label="추가로 쓰이는 인자 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>추가로 쓰이는 인자</h2>
<ul>
<li>bcrypt.gensalt(round=4) : round는 cost 인자로서 해쉬 함수를 반복할 횟수를 결정한다. 이 때 반복 횟수는 2^n이 된다.</li>
</ul>
<h2 id="예시"><a href="#%EC%98%88%EC%8B%9C" aria-label="예시 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>예시</h2>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"># bcrypt 임포트한다
import bcrypt
password = b&quot;super secret password&quot;
# 패스워드 해싱
hashed = bcrypt.hashpw(password, bcrypt.gensalt(14))
# DB 저장 패스워드 가져오기
user_data = User.objects.get(email=data[&quot;email&quot;])
user_password = user_data.password.encode(&#39;utf-8&#39;)
# 프론트에서 받은 패스워드 hashing
byted_password = bcrypt.hashpw(data[&#39;password&#39;], bcrypt.gensalt(14))
# 패스워드 체크
if bcrypt.checkpw(byted_password, user_password):
print(&quot;It Matches!&quot;)
else:
print(&quot;It Does not Match :(&quot;)</code></pre></div></content:encoded></item><item><title><![CDATA[Python Closure]]></title><description><![CDATA[closure in python]]></description><link>https://ctsictai.github.io//posts/python/closure</link><guid isPermaLink="false">https://ctsictai.github.io//posts/python/closure</guid><pubDate>Thu, 09 Jan 2020 23:30:03 GMT</pubDate><content:encoded><p>전에 봤던 데코레이터의 개념을 정확히 알기 위해서는 Closure를 알아야한다. Closure의 개념을 알기 위해서는 변수의 범위를 알아야한다.(SCOPE)
전에 정리를 한번했었는데 간단히 정리하고 넘어가도록 한다.</p>
<h1 id="변수의-사용-범위-알아보기"><a href="#%EB%B3%80%EC%88%98%EC%9D%98-%EC%82%AC%EC%9A%A9-%EB%B2%94%EC%9C%84-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0" aria-label="변수의 사용 범위 알아보기 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>변수의 사용 범위 알아보기</h1>
<p>Closure 개념을 알아보기 전에 변수의 사용범위에 대해 짚고 넘어간다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">x = 10 # 전역변수 func 함수 안에서도 유효하고 func 밖에서도 유효한 변수
def func():
a = 4 # 지역변수 - func 함수안에서만 유효한 변수
print(a) # --&gt; local scope --&gt; 정상 출력
print(a) # 에러남 --&gt; why? : 지역변수 a를 전역범위에서 사용했기 때문에
print(x) # 10 정상 출력</code></pre></div>
<h2 id="함수-안에서-전역변수-변경하기"><a href="#%ED%95%A8%EC%88%98-%EC%95%88%EC%97%90%EC%84%9C-%EC%A0%84%EC%97%AD%EB%B3%80%EC%88%98-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0" aria-label="함수 안에서 전역변수 변경하기 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>함수 안에서 전역변수 변경하기</h2>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">x = 10 # 전역변수 func 함수 안에서도 유효하고 func 밖에서도 유효한 변수
def func():
global x # 글로벌 변수 선언
x = 4 # 함수 내에서 뿐만 아니라 전역에서도 유효한 변수가됨
func() # func 함수 호출 global x --&gt; 4로 변경
print(x)
4 # func에서 선언된 global x 값으로 결과값</code></pre></div>
<h2 id="함수-안의-함수에서-지역변수-변경"><a href="#%ED%95%A8%EC%88%98-%EC%95%88%EC%9D%98-%ED%95%A8%EC%88%98%EC%97%90%EC%84%9C-%EC%A7%80%EC%97%AD%EB%B3%80%EC%88%98-%EB%B3%80%EA%B2%BD" aria-label="함수 안의 함수에서 지역변수 변경 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>함수 안의 함수에서 지역변수 변경</h2>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def A():
x = 10 # A의 지역 변수 x
def B():
x = 20 # x에 20 할당 -&gt; 이건 B의 지역변수로 위의 x와 다르다
B()
print(x) # A의 지역 변수 x 출력
A()
10 # A의 지역변수값 그대로 출력</code></pre></div>
<p>x값을 일치 하기 위해서는 지역변수값을 변경 시켜야 한다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def A():
x = 10 # A의 지역 변수 x
def B():
nonlocal x # 현재 함수의 바깥쪽에 있는 지역 변수 사용
x = 20 # A의 지역 변수 x에 20 할당
B()
print(x) # A의 지역 변수 x 출력
A()
20 # B에서 바뀐 값 20 이 출력</code></pre></div>
<ul>
<li>nonlocal이 지역변수를 찾는 순서
가까운 함수부터 지역 변수를 찾고, 지역 변수가 없으면 계속 바깥쪽으로 나가서 찾습니다.(계층적)</li>
</ul>
<p>실무에서는 이렇게 여러 단계로 함수를 만들 일은 거의 없다고 한다. 그리고 함수마다 이름이 같은 변수를 사용하기 보다는 변수 이름을 다르게 짓는 것이 좋습니다.</p>
<p>전역 변수는 코드가 복잡해졌을 때 변수의 값을 어디서 바꾸는지 알기가 힘듭니다. 따라서 전역 변수는 가급적이면 사용하지 않는 것을 권장합니다.</p>
<h1 id="closure란"><a href="#closure%EB%9E%80" aria-label="closure란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Closure란?</h1>
<p>어떤 함수 내부에서 정의된 함수는 클로저가 될 수 있으며, 클로저는 바깥 함수로부터 생성된 변수값을 변경 또는 저장할 수 있는 함수이다.</p>
<ul>
<li>언제 활용??<br>
지역 변수와 코드를 묶어서 사용하고 싶을 때 활용합니다. 또한, 클로저에 속한 지역 변수는 바깥에서 직접 접근할 수 없으므로 데이터를 숨기고 싶을 때 활용합니다.</li>
</ul>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def login_decorator(func):
def wrapper(self, request, *args, **kwargs): # Closure 부분
if &quot;Authorization&quot; not in request.headers:
return JsonResponse({&quot;ERROR_CODE&quot;:&quot;INVALID_LOGIN&quot;}, status=401)
encode_token = request.headers[&quot;Authorization&quot;] # request가 바깥 전역함수 login_decorator의 func에서 request 변수 중 headers에 있는 [&quot;Authorization&quot;]값
try:
data = jwt.decode(encode_token, SECRET[&#39;secret&#39;], algorithm=&#39;HS256&#39;)
user = User.objects.get(id = data[&quot;user_id&quot;]) request.user = user # request.user에 새로운 값 부여
except jwt.DecodeError:
return JsonResponse({&quot;ERROR_CODE&quot; : &quot;INVALID_TOKEN&quot;}, status = 401)
except User.DoesNotExist:
return JsonResponse({&quot;ERROR_CODE&quot; : &quot;UNKNOWN_USER&quot;}, status = 401)
return func(self, request, *args, **kwargs) # 바뀐 변수값을 리턴
return wrapper # 함수 자체를 리턴</code></pre></div>
<h2 id="lamda로-클로져-만들기"><a href="#lamda%EB%A1%9C-%ED%81%B4%EB%A1%9C%EC%A0%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0" aria-label="lamda로 클로져 만들기 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>lamda로 클로져 만들기</h2>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def calc():
a = 3
b = 5
return lambda x: a * x + b # 람다 표현식을 반환(함수 따로 안만들고)
c = calc()
print(c(1), c(2), c(3), c(4), c(5))</code></pre></div></content:encoded></item><item><title><![CDATA[Decorator]]></title><description><![CDATA[decorator example]]></description><link>https://ctsictai.github.io//posts/python/django/decorator</link><guid isPermaLink="false">https://ctsictai.github.io//posts/python/django/decorator</guid><pubDate>Wed, 08 Jan 2020 23:30:03 GMT</pubDate><content:encoded><h1 id="데코레이터란"><a href="#%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0%EB%9E%80" aria-label="데코레이터란 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>데코레이터란?</h1>
<p>함수(메서드)를 장식하는 개념으로 함수 앞뒤에 기능을 추가해서 손쉽게 함수를 활용할 수 있는 기법이다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class Calc:
@staticmethod # 데코레이터
def add(a, b):
print(a + b)</code></pre></div>
<h2 id="그러면-왜-쓸까"><a href="#%EA%B7%B8%EB%9F%AC%EB%A9%B4-%EC%99%9C-%EC%93%B8%EA%B9%8C" aria-label="그러면 왜 쓸까 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>그러면 왜 쓸까?</h2>
<p>함수나 클래스의 메서드는 한 함수에 한 기능을 넣는 것이 좋다.<br>
(Unit test를 생각한다면 더더욱 함수 하나에 한 기능을 넣어야 한다.)</p>
<p>그런데 한 함수에 한 기능을 넣기에는 애매한 경우가 있다.<br>
혹은 한가지 기능에 간단한 로직을 첨가하는 것이 좀 더 좋아지는 경우<br>
한 기능을 여러 메서드나 함수에서 계속적으로 사용할 때 함수마다 기능을 넣는 것은 계속 같은 코드가 중복되는 문제가 발생한다.</p>
<p>이럴 때 사용하는 것이 데코레이터이다.</p>
<h2 id="데코레이터-형태-설명"><a href="#%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0-%ED%98%95%ED%83%9C-%EC%84%A4%EB%AA%85" aria-label="데코레이터 형태 설명 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>데코레이터 형태 설명</h2>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def trace(func): # 호출할 함수를 매개변수로 받음
def wrapper(): # 호출할 함수를 감싸는 함수
print(func.__name__, &#39;함수 시작&#39;) # __name__으로 함수 이름 출력
func() # 매개변수로 받은 함수를 호출
print(func.__name__, &#39;함수 끝&#39;)
return wrapper # wrapper 함수 반환
# 함수안에서 함수를 만들고 반환하는 클로저 개념
def hello():
print(&#39;hello&#39;)</code></pre></div>
<blockquote>
<p>결과</p>
</blockquote>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">trace_hello = trace(hello) # 데코레이터에 호출할 함수를 넣음
trace_hello() # 반환된 함수를 호출
hello 함수 시작
hello
hello 함수 끝</code></pre></div>
<h2 id="데코레이터의-일반-형태"><a href="#%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0%EC%9D%98-%EC%9D%BC%EB%B0%98-%ED%98%95%ED%83%9C" aria-label="데코레이터의 일반 형태 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>데코레이터의 일반 형태</h2>
<p>데코레이터 앞에 @를 붙여준다. 그리고 데코레이터를 적용할 함수 앞 줄에 꼭 입력한다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">@데코레이터
def 함수이름():
코드</code></pre></div>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def trace(func): # 호출할 함수를 매개변수로 받음
def wrapper(): # 호출할 함수를 감싸는 함수
print(func.__name__, &#39;함수 시작&#39;) # __name__으로 함수 이름 출력
func() # 매개변수로 받은 함수를 호출
print(func.__name__, &#39;함수 끝&#39;)
return wrapper # wrapper 함수 반환
# 함수안에서 함수를 만들고 반환하는 클로저 개념
@trace # @데코레이터
def hello():
print(&#39;hello&#39;)</code></pre></div>
<h2 id="가변-인수를-가지는-데코레이터"><a href="#%EA%B0%80%EB%B3%80-%EC%9D%B8%EC%88%98%EB%A5%BC-%EA%B0%80%EC%A7%80%EB%8A%94-%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0" aria-label="가변 인수를 가지는 데코레이터 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>가변 인수를 가지는 데코레이터</h2>
<p>매개변수(인수)가 고정되지 않은 함수를 처리할 때 wrapper 함수를 가변 인수 함수로 만들면 됩니다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def trace(func): # 호출할 함수를 매개변수로 받음
def wrapper(*args, **kwargs): # 가변 인수 함수로 만듦
res = func(*args, **kwargs) # func에 args, kwargs를 언패킹하여 넣어줌
print(&#39;{0}(args={1}, kwargs={2}) -&gt; {3}&#39;.format(func.__name__, args, kwargs, r))
# 매개변수와 반환값 출력
return res # func의 반환값을 반환
return wrapper # wrapper 함수 반환
@trace # @데코레이터
def get_max(*args): # 위치 인수를 사용하는 가변 인수 함수
return max(args)
print(get_max(10, 20))
&gt; get_max(args=(10, 20), kwargs={}) -&gt; 20
&gt; 20</code></pre></div>
<h2 id="매개변수인자가-존재하는-데코레이터"><a href="#%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%EC%9D%B8%EC%9E%90%EA%B0%80-%EC%A1%B4%EC%9E%AC%ED%95%98%EB%8A%94-%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0" aria-label="매개변수인자가 존재하는 데코레이터 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>매개변수(인자)가 존재하는 데코레이터</h2>
<p>데코레이터는 값을 지정해서 동작을 바꿀 수 있습니다</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def is_multiple(x): # 데코레이터가 사용할 매개변수를 지정
def real_decorator(func): # 호출할 함수를 매개변수로 받음
def wrapper(a, b): # 호출할 함수의 매개변수와 똑같이 지정</code></pre></div>
<p>일반적인 데코레이터를 만들 때 함수 안에 함수를 하나만 만들었습니다. 하지만 매개변수가 있는 데코레이터를 만들 때는 함수를 하나 더 만들어야 합니다.</p>
<p>먼저 is<em>multiple 함수를 만들고 데코레이터가 사용할 매개변수 x를 지정합니다.(매개변수를 지정할 함수) 그리고 is</em>multiple 함수 안에서 실제 데코레이터 역할을 하는 real<em>decorator(일반적인 데코레이터 함수)를 만듭니다. 즉, 이 함수에서 호출할 함수를 매개변수로 받습니다. 그다음에 real</em>decorator 함수 안에서 wrapper 함수를 만들어주면 됩니다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def is_multiple(x): # 데코레이터가 사용할 매개변수를 지정
def real_decorator(func): # 호출할 함수를 매개변수로 받음
def wrapper(a, b): # 호출할 함수의 매개변수와 똑같이 지정
res = func(a, b) # func를 호출하고 반환값을 변수에 저장
if res % x == 0: # func의 반환값이 x의 배수인지 확인
print(&#39;{0}의 반환값은 {1}의 배수입니다.&#39;.format(func.__name__, x))
else:
print(&#39;{0}의 반환값은 {1}의 배수가 아닙니다.&#39;.format(func.__name__, x))
return res # func의 반환값을 반환
return wrapper # wrapper 함수 반환
return real_decorator # real_decorator 함수 반환</code></pre></div>
<p>여기서는 real_decorator, wrapper 함수를 두 개 만들었으므로 함수를 만든 뒤에 return으로 두 함수를 반환해줍니다.</p>
<p>데코레이터를 사용할 때는 데코레이터에 ( )(괄호)를 붙인 뒤 인수를 넣어주면 됩니다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">@데코레이터(인수)
def 함수이름():
코드</code></pre></div>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">@is_multiple(3) # @데코레이터(인수)
def add(a, b):
return a + b
print(add(10, 20))
&gt; add의 반환값은 3의 배수입니다.
&gt; 30</code></pre></div>
<h3 id="-데코레이터-여러개-지정하기"><a href="#-%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0-%EC%97%AC%EB%9F%AC%EA%B0%9C-%EC%A7%80%EC%A0%95%ED%95%98%EA%B8%B0" aria-label=" 데코레이터 여러개 지정하기 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>※ 데코레이터 여러개 지정하기</h3>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">@데코레이터1
@데코레이터2
def 함수이름():
코드</code></pre></div>
<p>데코레이터가 위에서부터 차례대로 실행된다.</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def decorator1(func):
def wrapper():
print(&#39;decorator1&#39;)
func()
return wrapper
def decorator2(func):
def wrapper():
print(&#39;decorator2&#39;)
func()
return wrapper
# 데코레이터를 여러 개 지정
@decorator1
@decorator2
def hello():
print(&#39;hello&#39;)
hello()
decorator1
decorator2
hello</code></pre></div>
<h1 id="실제-데코레이터-생성-예시"><a href="#%EC%8B%A4%EC%A0%9C-%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0-%EC%83%9D%EC%84%B1-%EC%98%88%EC%8B%9C" aria-label="실제 데코레이터 생성 예시 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>실제 데코레이터 생성 예시</h1>
<p>로그인 시 JWT 토큰을 발급하고 특정 페이지를 조회하거나 페이지를 게시할 때 로그인 유저인지 확인하기 위한 데코레이터</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def login_decorator(func):
def wrapper(self, request, *args, **kwargs):
if &quot;Authorization&quot; not in request.headers:
return JsonResponse({&quot;ERROR_CODE&quot;:&quot;INVALID_LOGIN&quot;}, status=401) # 웹페이지에서 기존에 발급받았던 토큰을 request.header에 실어서 보낸다. 이 때 아무것도 없다면 로그인이 안되있다고 판단하고 에러를 리턴한다.
encode_token = request.headers[&quot;Authorization&quot;] # 프론트에서 보낸 토큰
try:
data = jwt.decode(encode_token, SECRET[&#39;secret&#39;], algorithm=&#39;HS256&#39;)
user = User.objects.get(id = data[&quot;user_id&quot;]) # 토큰값에 있는 user_id와 user DB table에 있는 user_id와 비교
request.user = user # 프론트엔드에게 받은 request.user에 3번의 자료 저장 =&gt;프론트엔드에게 전달해주기 전 준비과정
except jwt.DecodeError: # 토큰값이 decode가 안될 시에 에러 리턴
return JsonResponse({&quot;ERROR_CODE&quot; : &quot;INVALID_TOKEN&quot;}, status = 401)
except User.DoesNotExist: # user가 존재하지 않는 경우 에러 리턴
return JsonResponse({&quot;ERROR_CODE&quot; : &quot;UNKNOWN_USER&quot;}, status = 401)
return func(self, request, *args, **kwargs) # 4번에 저장된 request를 데코레이터 리턴
=&gt; 데코레이터종료 및 프론트엔드에게 해당 유저의 정보를 리턴
return wrapper</code></pre></div>
<h3 id="실제-데코레이터-적용-예시"><a href="#%EC%8B%A4%EC%A0%9C-%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0-%EC%A0%81%EC%9A%A9-%EC%98%88%EC%8B%9C" aria-label="실제 데코레이터 적용 예시 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>실제 데코레이터 적용 예시</h3>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">@login_decorator # 데코레이터 함수 적용
def get(self, request): # 로그인 데코레이터 적용시킬 함수
user = request.user # request.user가 로그인 데코레이터에서 받은 변수값
data = [{
&quot;user_name&quot; : user.user_name,
&quot;user_email&quot; : user.email
}]
return JsonResponse({&quot;data&quot;: data}, status=200)</code></pre></div></content:encoded></item><item><title><![CDATA[Sorting Algorithm python]]></title><description><![CDATA[Sorting by Python]]></description><link>https://ctsictai.github.io//posts/algorithm/sorting/1</link><guid isPermaLink="false">https://ctsictai.github.io//posts/algorithm/sorting/1</guid><pubDate>Tue, 31 Dec 2019 23:30:03 GMT</pubDate><content:encoded><h1 id="프로그래머스-정렬-1번-문제"><a href="#%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%95%EB%A0%AC-1%EB%B2%88-%EB%AC%B8%EC%A0%9C" aria-label="프로그래머스 정렬 1번 문제 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>프로그래머스 정렬 1번 문제</h1>
<p>배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.</p>
<p>예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면</p>
<p>array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다.<br>
1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다.<br>
2에서 나온 배열의 3번째 숫자는 5입니다.<br>
배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요.</p>
<h3 id="제한사항"><a href="#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD" aria-label="제한사항 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>제한사항</h3>
<p>array의 길이는 1 이상 100 이하입니다.
array의 각 원소는 1 이상 100 이하입니다.
commands의 길이는 1 이상 50 이하입니다.
commands의 각 원소는 길이가 3입니다.</p>
<h3 id="입출력-예"><a href="#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88" aria-label="입출력 예 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>입출력 예</h3>
<table>
<thead>
<tr>
<th>array</th>
<th>commands</th>
<th>return</th>
</tr>
</thead>
<tbody>
<tr>
<td>[1, 5, 2, 6, 3, 7, 4]</td>
<td>[[2, 5, 3], [4, 4, 1], [1, 7, 3]]</td>
<td>[5, 6, 3]</td>
</tr>
</tbody>
</table>
<h3 id="입출력-예-설명"><a href="#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88-%EC%84%A4%EB%AA%85" aria-label="입출력 예 설명 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>입출력 예 설명</h3>
<ol>
<li>[1, 5, 2, 6, 3, 7, 4]를 2번째부터 5번째까지 자른 후 정렬합니다. [2, 3, 5, 6]의 세 번째 숫자는 5입니다.</li>
<li>[1, 5, 2, 6, 3, 7, 4]를 4번째부터 4번째까지 자른 후 정렬합니다. [6]의 첫 번째 숫자는 6입니다.</li>
<li>[1, 5, 2, 6, 3, 7, 4]를 1번째부터 7번째까지 자릅니다. [1, 2, 3, 4, 5, 6, 7]의 세 번째 숫자는 3입니다.</li>
</ol>
<h2 id="기본-로직"><a href="#%EA%B8%B0%EB%B3%B8-%EB%A1%9C%EC%A7%81" aria-label="기본 로직 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>기본 로직</h2>
<ol>
<li>배열 array를 슬라이스([:]) 하고 정렬(sorted)을 한다</li>
<li>정렬한 list에서 commands에 해당되는 인덱스의 값을 리턴한다.</li>
<li>리턴한 값을 answer list에 추가한다(append)</li>
<li>commands의 길이가 최대 50까지 이므로 반복문이 필요하다. (나는 while문으로 접근하였다.)</li>
</ol>
<h2 id="문제-풀이"><a href="#%EB%AC%B8%EC%A0%9C-%ED%92%80%EC%9D%B4" aria-label="문제 풀이 permalink" class="anchor"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>문제 풀이</h2>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def solution(array, commands):
answer = []
i = 0
while i &lt;= len(commands)-1:
ele = sorted(array[commands[i][0]-1:commands[i][1]])
m = ele[commands[i][2]-1]
answer.append(m)
i += 1
return answer</code></pre></div>
<ul>
<li>while문으로 commands의 리스트 길이만큼 돌린다.</li>
<li>배열 array를 슬라이스 하고 정렬까지 완료</li>
<li>정렬한 list에서 command에 있는 인덱스값으로 요소값 리턴</li>
<li>리턴한 요소값을 answer list에 요소 추가</li>
</ul>
<p>이렇게 풀었지만 더 간단히 푸는 방법이 있었다????</p>
<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">def solution(array, commands):
return list(map(lambda x: sorted(array[x[0]-1:x[1]])[x[2]-1], commands))</code></pre></div>
<ul>
<li>list에서 map과 람다함수를 이용해서 한 줄로 깔끔하게 풀어낸 모습이다.</li>