<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 17 Jun 2021 05:23:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sage_y" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[CORS 에러 발생 시 해결책]]></title>
            <link>https://velog.io/@sage_y/CORS-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D-%EC%8B%9C-%ED%95%B4%EA%B2%B0%EC%B1%85</link>
            <guid>https://velog.io/@sage_y/CORS-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D-%EC%8B%9C-%ED%95%B4%EA%B2%B0%EC%B1%85</guid>
            <pubDate>Thu, 17 Jun 2021 05:23:53 GMT</pubDate>
            <description><![CDATA[<p>웹 개발을 하다보면 CORS 에러와 자주 마주하게 된다.</p>
<p>CORS는 간단히 얘기하자면, 다른 출처 간 자원 공유가 이뤄질 수 없다는 것이다.
여기서 얘기하는 출처란 <strong>scheme, 도메인, 포트</strong> 모든 것을 포함한다.</p>
<p>만약 클라이언트를 3000번, 서버를 5000번 포트에 띄웠다면 클라이언트에서 서버를 호출할 수 없는 문제가 발생한다.</p>
<p>따라서, 서버에서 CORS를 허용하는 작업을 따로 해주어야한다.</p>
<p>flask의 경우 flask-cors 라이브러리를 이용하여 해결할 수 있다.</p>
<pre><code class="language-python">import flask
from flask-cors import CORS

app = Flask(__name__)
CORS(app)</code></pre>
<p>초 심플!</p>
<hr>
<p><span style="font-size:30px;color:red">하지만</span> cookie에 유저 정보를 저장하고 이를 클라이언트 - 서버 간에 주고 받아야 한다면 일이 살짝 복잡해진다.</p>
<p>cross-origin request 경우에 user credentials(cookie 등)의 전송이 제한되어 있기 때문이다. (same-origin의 경우에는 기본적으로 허용되어 있다.)</p>
<p>따라서 user credentials를 전송하겠노라고 별도로 명시해줘야한다.</p>
<p><strong>1. 클라이언트(javascript, axios)</strong></p>
<pre><code class="language-javascript">import axios from &quot;axios&quot;;

const client = axios.create({
    baseURL: &quot;localhost:5000&quot;,
    withCredentials: true,
});</code></pre>
<p><strong>2. 서버(python, flask)</strong></p>
<pre><code class="language-python">import flask
from flask-cors import CORS

app = Flask(__name__)
CORS(app, supports_credentials=True)</code></pre>
<p>_credentials 관련 항목을 모두 true로 설정_해주었다.</p>
<p><span style="color:red">끝난줄 알았지?</span></p>
<p>이 상태에서 요청을 보낼 경우 아래와 같은 에러가 발생한다.</p>
<blockquote>
<pre><code>Header in the response must not be the wildcard &#39;*&#39; when the request&#39;s credentials mode is &#39;include&#39;</code></pre></blockquote>
<pre><code>
간단히 말하면 credential이 포함된 데이터를 주고받을 때는 &#39;access-control-allow-origin&#39;을 와일드카드(\*)로 설정할 수 없다는 것이다.
access-control-allow-origin이 &quot;\*&quot;인 경우 서버는 다른 어떤 크로스 도메인으로부터의 요청도 수용한다.

보통의 경우라면 괜찮지만, credentials의 전송을 허용하는 경우에는 임의의 도메인으로부터 요청을 받으면 보안에 취약해질 수 있다.

따라서 요청을 받을 도메인을 한정해야 한다.

실제로 [flask-cors docs](https://flask-cors.readthedocs.io/en/latest/api.html#flask_cors.CORS)에도 supports_credentials=True로 설정하기 위해서는 origin이 &quot;\*&quot;면 안된다고 나와있다.

아래와 같이 할 수 있다.</code></pre><p>import flask
from flask-cors import CORS</p>
<p>app = Flask(<strong>name</strong>)
CORS(app, supports_credentials=True, origins=&quot;localhost:3000&quot;)</p>
<p>```</p>
<p>origins에는 string뿐만 아니라 list가 들어갈 수있다.</p>
<p>#cors #credentials</p>
<p><del>업무 중에 알게 된 사실을 빠르게 적어내느라 일부 내용이 빠져있다.</del>
추후 추가할 내용</p>
<ul>
<li><input disabled="" type="checkbox"> preflight request</li>
<li><input disabled="" type="checkbox"> jwt 및 jwt 옵션</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] pyenv와 virtualenv]]></title>
            <link>https://velog.io/@sage_y/Python-pyenv%EC%99%80-virtualenv</link>
            <guid>https://velog.io/@sage_y/Python-pyenv%EC%99%80-virtualenv</guid>
            <pubDate>Fri, 19 Jun 2020 04:54:41 GMT</pubDate>
            <description><![CDATA[<h3>pyenv</h3>
파이썬 버전 관리 툴이다.

<p>주요 명령어:</p>
<p><code>pyenv install -l</code> : 설치 가능한 버전 목록을 확인
<code>pyenv install &lt;version&gt;</code>: 특정 버전을 설치
<code>pyenv versions</code>: 설치되어 있는 버전을 확인
<code>pyenv shell &lt;version&gt;</code>: 특정 버전 shell 실행</p>
<ul>
<li>버전은 python, anaconda, miniconda 등으로 나뉜다.</li>
</ul>
<h3>virtualenv</h3>
파이썬 가상환경 관리 툴이다.
a 라는 패키지가 있을 때
A 프로젝트에는 a의 1.0 버전이,
B 프로젝트에는 a의 2.0 버전이 필요하다고 하자.

<p>두 개 버전은 호환이 되지 않는다.</p>
<p>즉, A 프로젝트에서 2.0버전을 사용할 수 없다.</p>
<p>이런 경우 virtualenv를 사용해 문제를 간단히 해결할 수 있다.</p>
<h3>pyenv+virtualenv</h3>
버전 및 가상환경 관리를 동시에 하는 것이 깔끔하다.

<p>주요 명령어:</p>
<p><code>pyenv virtualenv &lt;version&gt; &lt;env_name&gt;</code>: 특정 버전의 가상환경을 생성한다.
<code>pyenv local &lt;env_name&gt;</code>: 특정 디렉터리의 가상환경을 설정한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[API Documentation]]></title>
            <link>https://velog.io/@sage_y/API-Documentation</link>
            <guid>https://velog.io/@sage_y/API-Documentation</guid>
            <pubDate>Sun, 24 May 2020 07:55:03 GMT</pubDate>
            <description><![CDATA[<h3 id="openapi-specification">OpenAPI Specification</h3>
<p>REST API를 위한 API description format으로, YAML이나 JSON 형식으로 쓰인다.</p>
<p>OpenAPI Specification: <a href="https://swagger.io/docs/specification/about/">https://swagger.io/docs/specification/about/</a></p>
<p>잘 정리된 API 명세는 API 개발자 본인과 API를 사용하는 모든 사람에게 도움이 된다.</p>
<h3 id="swagger">Swagger</h3>
<p>사용자가 REST API를 쉽게 설계하고, 만들고, 문서화하고, 또 사용하도록 도와주는 오픈소스 소프트웨어 프레임워크다.</p>
<p>Swagger tool 중 하나인 Swagger Editor를 이용해 OpenAPI 기반 API 명세를 작성해 볼 수 있다.</p>
<p><a href="https://swagger.io/tools/swagger-editor/">https://swagger.io/tools/swagger-editor/</a></p>
<p>브라우저 기반 에디터로, 변경한 내용이 바로 화면에 반영된다.</p>
<h3 id="redoc">ReDoc</h3>
<p><a href="https://github.com/Redocly/redoc">https://github.com/Redocly/redoc</a></p>
<p>위에서 Swagger Editor로 작성한 YAML, JSON 파일을 더 깔끔하고 가독성 좋은 페이지로 렌더링 해준다.</p>
<p>redoc-cli를 이용하여 html 파일을 만들 수 있다.</p>
<p>redoc-cli 설치</p>
<pre><code>npm install -g redoc-cli</code></pre><p>html 파일 생성</p>
<pre><code>redoc-cli bundle -o [output filename] [source filename]</code></pre><h4 id="참고">참고</h4>
<ul>
<li><p>redoc-cli를 설치하기 위해서는 일정 버전 이상의 node와 npm이 설치되어 있어야 한다.
node 및 npm 버전 업데이트는 <a href="&#39;https://velopert.com/1351&#39;">이 글</a>을 참고했다.</p>
</li>
<li><p>remote server에서 html 파일 실행</p>
<pre><code># python2
python -m SimpleHTTPServer [port]
</code></pre></li>
</ul>
<h1 id="python3">python3</h1>
<p>python -m http.server [port]
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[최고의 폰트를 찾아서]]></title>
            <link>https://velog.io/@sage_y/%EC%B5%9C%EA%B3%A0%EC%9D%98-%ED%8F%B0%ED%8A%B8%EB%A5%BC-%EC%B0%BE%EC%95%84%EC%84%9C</link>
            <guid>https://velog.io/@sage_y/%EC%B5%9C%EA%B3%A0%EC%9D%98-%ED%8F%B0%ED%8A%B8%EB%A5%BC-%EC%B0%BE%EC%95%84%EC%84%9C</guid>
            <pubDate>Mon, 04 May 2020 17:51:30 GMT</pubDate>
            <description><![CDATA[<p>폰트 다운 -&gt; 적용 -&gt; 터미널 및 에디터 확인 뻘짓을 반복하다가</p>
<p>웹 상에서 바로 적용해볼 수 있는 좋은 사이트를 찾았다.</p>
<p>프로그래밍용 폰트로 유명한 폰트는 거의 다 있는 듯 싶다.</p>
<p><a href="https://app.programmingfonts.org">https://app.programmingfonts.org</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Vscode 폰트가 굵어보이는 문제 해결 방법(MacOS)]]></title>
            <link>https://velog.io/@sage_y/Vscode-%ED%8F%B0%ED%8A%B8%EA%B0%80-%EA%B5%B5%EC%96%B4%EB%B3%B4%EC%9D%B4%EB%8A%94-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95MacOS</link>
            <guid>https://velog.io/@sage_y/Vscode-%ED%8F%B0%ED%8A%B8%EA%B0%80-%EA%B5%B5%EC%96%B4%EB%B3%B4%EC%9D%B4%EB%8A%94-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95MacOS</guid>
            <pubDate>Mon, 04 May 2020 17:45:33 GMT</pubDate>
            <description><![CDATA[<p><span style="color:red">*주의: MacOS에 한한 해결 방법이다.</span>
<br>
나는야 좋은 폰트를 찾아 헤매는 하이에나..</p>
<p>폰트를 적용하고 콘솔 및 vscode 에디터에서 어떤 느낌인지 확인하기를 여러 번..</p>
<p>근데 한 가지 이상한 점을 발견했다.</p>
<p>동일한 폰트 및 굵기임에도 불구하고 콘솔에서보다 vscode에서 훨씬 굵어보이는 것..!</p>
<p>갓구글 선생님의 도움으로 해결 방법을 알아 낼 수 있었다.</p>
<p>혹시 나처럼 <del>예민보스</del>인 사람들에게 도움이 될까 싶어 내가 어떻게 해결했는지 기록해둔다. 
<br>
<code>시스템 환경설정</code> &gt; <code>일반</code> &gt; 제일 아래 <code>사용 가능할 때 부드러운 서체 사용(Use font smoothing when availabe</code>을 체크 해제
<br>
해당 옵션을 체크해놓은 기억이 없는걸 보면 기본 설정인 듯 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RAII(Resource Acquisition is Initialization) 디자인 패턴]]></title>
            <link>https://velog.io/@sage_y/RAIIResource-Acquisition-is-Initialization-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@sage_y/RAIIResource-Acquisition-is-Initialization-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Sun, 03 May 2020 06:57:54 GMT</pubDate>
            <description><![CDATA[<p>GC(Garbage Collector)를 제공하는 다른 많은 언어와 달리 C++은 프로그래머가 직접 resource를 관리 해주어야 한다.</p>
<p>따라서 메모리 누수(memory leak)의 위험이 곳곳에 도사리고 있다.
<br>
실수로 메모리 해제 코드를 작성하지 않을 수도 있고,</p>
<p>작성했다고 하더라도 exception 발생으로 코드가 끝까지 실행되지 않아 메모리 해제에 실패할 수도 있다.
<br>
메모리 누수로 인해 메모리 사용량이 계속 증가하다보면 메모리 부족으로 프로그램이 crash 될 수 있다.</p>
<p>이를 방지하고자  C++ 창시자인 Bjarne Stroustrup는 <code>RAII(Resource Acquisition is Initialization)</code> 디자인 패턴을 제안했다. 
<br>
<strong>RAII란 객체의 생성과 동시에 자원을 할당하고 객체가 파괴될 때 자원을 해제하는 방법이다.</strong>
<br>
예외가 발생해서 예상치 못하게 함수를 빠져 나가더라도 함수 stack 내에서 선언된 모든 객체는 그 소멸자가 호출된다. (stack unwinding)</p>
<p>이 점을 이용하여 소멸자 안에 자원을 해제하는 코드를 작성하면 메모리 누수의 위험으로부터 해방될 수 있다.</p>
]]></description>
        </item>
    </channel>
</rss>