오픈 소스에 보면 항상 주제별로 메일링 리스트를 오픈하여 관리하는데, 이것은 mailman같은것으로 관리 되곤 했었다. 그래서 언젠가 이런곳에서도 혁신의 여지가 많이 있겠다 막연히 생각했었는데 그런 제품이 있었다. 이름하여 mailchimp. subscriber수가 많아지면 유료이므로 선택시 참고할 것.
mailchimp
mailchimp는 한마디로 메일링 리스트 관리 + 이메일 발송 + 데이터 분석의 역할을 하고 있다. 데이터 분석까지는 많이 써봐야 진가를 알 수 있을것 같으니 생략하고 메일링 리스트와 + 이메일 발송 까지 다뤄보기로 함.
static web site(github page 같은)를 사용하고 있는 경우, 메일링 리스트를 구현하려고 하면 DB까지 연결해야 하나라는 고민이 있을 수 있는데, 그럴때 mailchimp를 사용하면 좋겠다. subscibe form도 제공해줘서 static web에 바로 붙일 수 있다.
요즘 대부분의 사이트의 회원가입/로그인 화면을 보면 Facebook/Google/Twitter를 통해서 가입 및 로그인을 할 수 있게 만들어 놨다. 이것이 흥한 이유는 매번 같은 정보를 기입해야 하는 유저들이 버튼 한번만 클릭하면 되는 편리함 + 중/소 사이트들의 security에 불안을 느끼기 때문이기도 함.
이러한 것을 가능하게 해주는 것이 OAuth란 스펙인데 현재는 2.0이 대부분임.
OAuth2
OAuth가 없던 시절에 이런것을 하려고 하면, 우선 나의 앱(client)이 페이스북 계정과 연동하게 하려면 아이디/패스워드를 클라이언트에게 노출 될 수밖에 없고, 이렇게 되면 내가 페북의 비번관리를 잘못하면 비번이 노출되게 되고 그러면 페이스북의 비번을 뚫리게 되므로 보안적으로 허술해짐.
그래서 고안한 것이 OAuth인데, 비번 대신에 access_token 을 발급해주고, 필요한 정보가 있으면 access_token으로 쿼리를 하면 답을 주겠다는 것임. 아래 flow 참고.
facebook/google/twitter로서는 당연히 자신의 계정이 많으 퍼질수록 좋음. 그래서 3rd party가(sign up을 쉽게 하고자 하는) 자신의 앱을 등록할 수 있게 해줌. 이때 app id 와 app secret 을 발급하주고, 이것을 이용해서 oauth의 endpoint로 로그인을 요청하면 로그인 결과를 redirect_uri로 리턴해줌. 리턴시 access token을 보내주는 flow!
fb/google/twitter로서도 app_id로 3rd party들을 컨트롤할 수 있으니 이보다 계정 오너로서는 이보다 더 좋을순 없음. 점점 모든 데이터는 빅 플레이어들에게 유리하게 가는 구조.
ELK 스택으로 많이 알려져있고, Elastic search(이하 ES) + LogStash + Kibana 의 조합으로 많이 사용한다. ES는 document DB이고, logStash는 로그를 정제하여 ES에 전달하는 역할, Kibana는 로그들을 필터링 및 조합하여 visualization을 하는 역할을 한다. 특히 타임 series 데이터를 보여주는데 적합하고 멋들어지게 보여줄 수 있어 선호되고 있다.
위에서 들어온 데이터를 Kibana로 visualize해주면 되는데 kibana의 직관적인 UI가 훌륭하다. 리프레쉬 간격도 설정 가능하고 시간간격도 자동으로 조절해준다. 그래프 수준은 훌륭하고 손쉽게 다양한 옵션으로 그래프를 그릴수 있다.
전체적인 흐름은 Management 에서 index설정을 하고, Discover에서 실험을 한후, visualize에서 시각화 설정을 해주고, dashboard에서 시각화한 요소들을 조합해서 한번에 볼수 있게 해주면 된다. 아래는 visual builder로 2개의 값을 비교해서 시간 축으로 나타낸 것이다.
Angular2와 React는 동시에 뜨더니 요즘은 React가 더 많이 쓰는것 같긴 하다. 하지만 그전에 이미 Angular2를 사용하기로 정했기에 계속 사용하고 있는데 문제는 Angular2와 딱 맞아 떨어지는 CSS Framework이 없어서 불편하다는 것.
Angular2는 typescript를 사용하고 IDE에서 fully 사용하려면 type definition도 필요히다. 그래서 선택에 제약이 좀 있다. 처음에는 Angular Material을 사용했는데, 보다시피 layout쪽 컴포넌트가 많이 약하다. 그래서인지 버전명에 아직도 beta가 붙어있다. Bootstrap/Sematic 등은 모두 훌륭한데, Angular에서 완벽하게 사용하려면 java script를 사용해야 하는데 이것을 사용하려면 설정을 더 해야 한다. 새로운 ng-bootstrap이나 ng-semantic도 있긴 하지만 컴포넌트 지원이 완벽하진 않다.
그래서 내가 semantic의 javascript api를 사용하기 위해서 했던 방법을 공유해보고자 한다. 여기선 semantic에 대해서만 얘기했지만 bootstrap도 다를것은 없다. 그리고 장기적으로는 Material처럼 Angular native css framework이 나오는 것이 제일 좋겠다. 그것이 Angular Material이 되겠지만.. 이것만 쓰기에는 컴포넌트가 많이 부족하다.
setup
우선 semantic는 내부적으로 jquery를 사용하고 있기 때문에 jquery를 추가 해줘야 된다. 패키징 방식에 따라서 아래처럼 CDN 링크를 사용할 수도 있고, angular-seed라면, {src: 'jquery/dist/jquery.min.js', inject: true}, 를 NPM_DEPENDENCIES에 추가해주면 된다.
vpc를 구성할때 CIDR notation이 나오는데 여기를 보면 자세하게 설명 되어 있다.
ip주소는 255가 맥스인 4개의 int로 구성되니까 한 자리에 8bit(255) 즉, 32bit가 된다. a.b.c.d/x의 의미는 a.b.c.d에서 앞의 x bit까지는 같다는 것을 의미. 예를 들어 10.10.1.44는 10.10.1.32와 초기 27비트가 같으므로(아래 참조) 사이더 블록 10.10.1.32/27에 일치한다. 10.10.1.0/24는 10.10.1.까지는 똑같고 마지막 자리만 다른 ip가 할당될 것이라는 뜻이다.
route table은 패킷이 어디로 가야 할지를 명시해 줌. most specific이 먼저 처리 됨. 아래의 경우 172.31.x.x는 같은 vpc로 흐르고, 나머지는 외부 인터넷으로 라우팅 되게 된다.
1 2
172.31.0.0/16 local 0.0.0.0/0 igw-3376c756
internet gateways로 패킷을 보내면 internet(외부)로 나가게 된다.
RDS
rds launching시에 subnet 관련 에러가 나면, 이것 참고. vpc의 subnet이 2개 이상이어야 하고, 그 2개는 availability zone이 달라야 한다.
security group
logical firewall이랄까.. inbound/outboud로 ip 대역이나, 특정 security group, ip 로 액세스를 허용할 수 있다.
EC2에서 RDS로 접속이 안될때 보통 security group에 막혀서 인 경우가 많다.
route53
hosted zone 설정한후, 브라우져에서 www.domain.com 은 잘 접속이 되는데, domain.com이 안될 경우는 A record set을 추가해주면 되는데 domain.com을 www.domain.com으로 alias해주면 www.domain.com으로 redirect됨.
A record는 ip address로 리졸브가 되지만, cname record은 다른 도메인으로 리졸브 될 수 있다. record type은 위키피디아를 참조
ECS는 EC2 instance를 사용해 container image를 사용할 수 있게 해주는 AWS의 컨테이너 서비스 이다. ECS는 크게 docker registry, Tasks Definition, Clusters 로 구성되어 있다.
docker registory는 docker hub같은 docker image를 저장할 수 있는 서비스인데 private registry서비스 이니 소스코드가 들어간 이미지도 push할 수 있고 secure하다.
Tasks definition은 docker run할때 많은 옵션을 줄 수 있는데 이것을 Tasks definition으로 추상화 한것 이다. 예를 들어 포트 매핑(-p), volume mount, 메모리 제한, network setting 등등..
Clusters는 주어진 클러스터에서 유동적으로 EC2 instance에 명시한 task를 실행할 수 있게 하는 추상화 이다. 어떤 EC2 instance를 사용할지, security group은 무엇을 사용할지, 허용가능한 instance는 몇대나 되는지 등등을 설정할 수 있다.
create docker registry
AWS console > ECS > Repositories > Create repository 에 들어가서 repository 이름을 명시하면 private docker registry를 생성할 수 있다. 이때 읿반적인 docker registry와 다른 점은 이름은 정해져 있다는 것이다. 즉, <registry_ip>/<image_name>:<tag> 에서 image_name이 <registry_url>/<image_name>은 정해진다는 것. tag만 수정할 수 있다.
이렇게 repository 생성후, 아래 순서로 docker image를 push 하면 된다.
1 2 3 4 5
aws configure # awscli를 사용하려면 access_key와 secret key등록이 되어 있어야 함. aws ecr get-login --region us-west-2 # 이 명령을 내리면 docker login command가 출력되니, 이 명령으로 docker login을 수행. docker build -t test . # docer image 빌드 docker tag test:latest <id>.dkr.ecr.us-west-2.amazonaws.com/test:latest # 이름 수정후 docker push <id>.dkr.ecr.us-west-2.amazonaws.com/test:latest # 푸쉬
nginx cluster 띄워 보기
nginx task 생성
에제로 nginx task 를 생성
AWS console > ECS > Task Definitions > Create new Task Definition 에서
요즘 추세인 REST + {Angular, React,} 등을 만들기 위해서는 백엔드가 rest api가 되어야 하는데 그것을 Django Frameowrk위에서 구현한 것이 Django Rest Framework이다. 기존에 Django에 관한 post를 올렸는데, REST API backend를 가지게 되면 안드로이드/iOS 어플등도 지원할 수 있게 되고 테스트도 쉽게 만들 수 있어 장점이 있다.
아래애서 사용할 Snippet 모델을 아래 처럼 정의한다.
1 2 3 4 5 6 7 8
classSnippet(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') code = models.TextField() linenos = models.BooleanField(default=False) language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100) style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100) owner = models.ForeignKey(User, on_delete=models.CASCADE)
Serializer
우선 이전 포스트에서 Model의 개념은 나왔고, Serializer개념을 이해해야 한다. Model 이 Serializer를 통해서 request/response를 받는다고 생각하면 된다. Serializer는 어떻게 매핑하여 클라이언트에게 돌려줄지, 클라이언트에서 받은 데이터를 어떻게 가공하여 모델에 집어넣을지를 맵핑해주는 레이어라고 생각하면 된다.
예를 들어, 위의 Snippet 모델에 owner field는, DB에는 primary key인 int로 저장 된다. 이것을 REST API로 보낼때는 int로 돌려줄 수도 있고, 아니면 owner의 정보를 볼 수 있는 url(HyperlinkedRelatedField)로 보내줄 수 도 있다. 이렇든 같은 데이터라도 어떤 형식으로 보내줄지는 요구사항마다 달라질 수 있다. 그래서 이것을 유연하게 대처하도록 Serializer라는 개념으로 추상화 했다.
1 2
read (from client to server): request -> serializer -> model write(from server to client): model -> serializer -> response
fields vs read_only_fields
fields에 명시된 것은 get/post 시에 나타날 field들을 명시하는 것이다. get에는 필요하지만, post/put시에는 넣을수 없는 정보는 read_\only_fields 로 명시해 주면 된다.
아래 예저의 경우 get시에는 user 필드도 받지만 post시에는 넣어주지 않아도 된다.
ViewSet은 Serializer를 통한 오브젝트를 Json으로 렌더링하거나 html로 렌더링을 담당하는 View 이다. 보통은 Model기반으로 하는 ModelViewSet을 많이 사용한다. get/post등의 default implementation이 있기 때문에 대부분은 그대로 사용하면 된다.
perform_create는 post로 실제 모델을 생성하기 전에 불리는 콜백인데, 여기서 POST에서 전달받지 못한 필드들을 초기화 해줄수 있다. 여기서는 owner정보를 채우고 있다.
permission_classes는 access control를 위해서 사용되는데, 로그인한 사용자들에게만 POST를 허용하고 READ는 다 허용하겠다는 정책이 permisson.IsAuthenticatedOrReadOnly이고, owner가 write권한을 아니면 read권한만 주는 것이 IsOwnerOrReadOnly 퍼미션이다. 여기서 read라 함은 get/list 이고, write는 post/put을 얘기한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSnippetViewSet(viewsets.ModelViewSet): """ This viewset automatically provides `list`, `create`, `retrieve`, `update` and `destroy` actions. Additionally we also provide an extra `highlight` action. """ queryset = Snippet.objects.all() serializer_class = SnippetSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,)
회사 proxy에 사설 인증서를 사용하는 경우가 있는데(우리회사 –), 이런 경우 인증서가 공인인증기관에서 인증된 것이 아니기 때문에 https handshake에서 에러가 난다. 해킹 기법의 하나인 main in the middle 을 회사가 하고 있는 것이다. 이런 회사의 경우 모든 패킷은 회사가 들여다 볼 수 있기때문에 privacy 침해의 소지가 다분하다.
이럴때 https 통신이 실패하지 않게 하려면 어떤 설정이 필요한지 각각의 경우에 대해서 정리해 봤다.
Mac
맥은 기본적으로 사설 인증서를 키체인에 등록하고 그 인증서를 System Keychains에 추가한다. 그 인증서를 선택하여 always trust로 해준다. 이렇게 하면 Chrome이나 curl등이 cert error를 내는것을 해결할 수 있다.
Java
JDK가 설치된 폴더의 cacerts 파일에 keytool을 이용해서 추가해주면 된다. 아래처럼