<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>가자공부하러!</title>
    <link>https://dotheright.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 12 Aug 2026 17:07:14 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>오피스엑소더스</managingEditor>
    <image>
      <title>가자공부하러!</title>
      <url>https://tistory1.daumcdn.net/tistory/3042217/attach/7bf8d6abba9843919f9b8adeda25fd35</url>
      <link>https://dotheright.tistory.com</link>
    </image>
    <item>
      <title>주은 마그넷 후보 - 황금산 민주은</title>
      <link>https://dotheright.tistory.com/365</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;황금산 민주은&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.54.45.png&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;1100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crgUS8/dJMcabqVAH7/hRAJWhhukQGCYUKQ1qvxSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crgUS8/dJMcabqVAH7/hRAJWhhukQGCYUKQ1qvxSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crgUS8/dJMcabqVAH7/hRAJWhhukQGCYUKQ1qvxSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrgUS8%2FdJMcabqVAH7%2FhRAJWhhukQGCYUKQ1qvxSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1038&quot; height=&quot;1100&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.54.45.png&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;1100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-10-30T18_11_35.000_mfe.jpg&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3NywM/dJMcagMy8V4/1Km3GY0W2LstaPRhJ3kW7k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3NywM/dJMcagMy8V4/1Km3GY0W2LstaPRhJ3kW7k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3NywM/dJMcagMy8V4/1Km3GY0W2LstaPRhJ3kW7k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3NywM%2FdJMcagMy8V4%2F1Km3GY0W2LstaPRhJ3kW7k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1234&quot; height=&quot;1600&quot; data-filename=&quot;2025-10-30T18_11_35.000_mfe.jpg&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.53.24.png&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pFqUr/dJMcagMy8V7/Wo80BNtAwUtg2TJr9QI5rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pFqUr/dJMcagMy8V7/Wo80BNtAwUtg2TJr9QI5rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pFqUr/dJMcagMy8V7/Wo80BNtAwUtg2TJr9QI5rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpFqUr%2FdJMcagMy8V7%2FWo80BNtAwUtg2TJr9QI5rk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1876&quot; height=&quot;1482&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.53.24.png&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1482&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.50.50.png&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/42COU/dJMcabqVAH4/olsVNzURrkW03ixcyITILK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/42COU/dJMcabqVAH4/olsVNzURrkW03ixcyITILK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/42COU/dJMcabqVAH4/olsVNzURrkW03ixcyITILK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F42COU%2FdJMcabqVAH4%2FolsVNzURrkW03ixcyITILK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;804&quot; height=&quot;920&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.50.50.png&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.45.26.png&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;1022&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctN6Ha/dJMcagMy8V6/MwOEeVTr7kZXOkuK3Yc1zK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctN6Ha/dJMcagMy8V6/MwOEeVTr7kZXOkuK3Yc1zK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctN6Ha/dJMcagMy8V6/MwOEeVTr7kZXOkuK3Yc1zK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctN6Ha%2FdJMcagMy8V6%2FMwOEeVTr7kZXOkuK3Yc1zK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1110&quot; height=&quot;1022&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.45.26.png&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;1022&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.44.43.png&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KAPZX/dJMcabqVAH5/k82AxsJJ6WYhyR5SjlDfM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KAPZX/dJMcabqVAH5/k82AxsJJ6WYhyR5SjlDfM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KAPZX/dJMcabqVAH5/k82AxsJJ6WYhyR5SjlDfM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKAPZX%2FdJMcabqVAH5%2Fk82AxsJJ6WYhyR5SjlDfM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;848&quot; height=&quot;940&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.44.43.png&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.44.06.png&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;1074&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N9ZXI/dJMb99T9lrA/MjHdSb2flY1RXMuDlVffV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N9ZXI/dJMb99T9lrA/MjHdSb2flY1RXMuDlVffV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N9ZXI/dJMb99T9lrA/MjHdSb2flY1RXMuDlVffV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN9ZXI%2FdJMb99T9lrA%2FMjHdSb2flY1RXMuDlVffV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1100&quot; height=&quot;1074&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.44.06.png&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;1074&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.43.19.png&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;1052&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0ADua/dJMb99T9lry/8lRAqjLZeNAWkU2tFTQGS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0ADua/dJMb99T9lry/8lRAqjLZeNAWkU2tFTQGS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0ADua/dJMb99T9lry/8lRAqjLZeNAWkU2tFTQGS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0ADua%2FdJMb99T9lry%2F8lRAqjLZeNAWkU2tFTQGS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;910&quot; height=&quot;1052&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.43.19.png&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;1052&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.42.50.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;786&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKpRh1/dJMcabqVAH2/vjPtzn0psjJO14WSCqW4f0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKpRh1/dJMcabqVAH2/vjPtzn0psjJO14WSCqW4f0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKpRh1/dJMcabqVAH2/vjPtzn0psjJO14WSCqW4f0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKpRh1%2FdJMcabqVAH2%2FvjPtzn0psjJO14WSCqW4f0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;786&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.42.50.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;786&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.39.04.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;1190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/peKla/dJMcabqVAH8/oZMzXC7liJd5VPqKXUlkKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/peKla/dJMcabqVAH8/oZMzXC7liJd5VPqKXUlkKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/peKla/dJMcabqVAH8/oZMzXC7liJd5VPqKXUlkKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpeKla%2FdJMcabqVAH8%2FoZMzXC7liJd5VPqKXUlkKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;894&quot; height=&quot;1190&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.39.04.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;1190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.37.31.png&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;858&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3rcg5/dJMcabqVAH3/rO6vWOXtnE0sT6Hgk05p81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3rcg5/dJMcabqVAH3/rO6vWOXtnE0sT6Hgk05p81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3rcg5/dJMcabqVAH3/rO6vWOXtnE0sT6Hgk05p81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3rcg5%2FdJMcabqVAH3%2FrO6vWOXtnE0sT6Hgk05p81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;858&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.37.31.png&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;858&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.36.36.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;958&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byqxOP/dJMb99T9lrz/UAhgYrxGuq41oI0pwUnpfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byqxOP/dJMb99T9lrz/UAhgYrxGuq41oI0pwUnpfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byqxOP/dJMb99T9lrz/UAhgYrxGuq41oI0pwUnpfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyqxOP%2FdJMb99T9lrz%2FUAhgYrxGuq41oI0pwUnpfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;912&quot; height=&quot;958&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.36.36.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;958&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.36.06.png&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nkidH/dJMcabqVAH6/x9zTxTEAWrca3dLBI6rMiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nkidH/dJMcabqVAH6/x9zTxTEAWrca3dLBI6rMiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nkidH/dJMcabqVAH6/x9zTxTEAWrca3dLBI6rMiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnkidH%2FdJMcabqVAH6%2Fx9zTxTEAWrca3dLBI6rMiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;840&quot; height=&quot;800&quot; data-filename=&quot;스크린샷 2026-05-20 오전 11.36.06.png&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>육아/주은</category>
      <category>남양주시</category>
      <category>민주은</category>
      <category>황금산</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/365</guid>
      <comments>https://dotheright.tistory.com/365#entry365comment</comments>
      <pubDate>Thu, 4 Jun 2026 23:56:02 +0900</pubDate>
    </item>
    <item>
      <title>주은콘 202506 ~ 202603(2) - 황금산 민주은</title>
      <link>https://dotheright.tistory.com/364</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;황금산 민주은!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_ew.png&quot; data-origin-width=&quot;174&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chuOPX/dJMb997GQ2N/e4GI261QLEG8BKziv1KqeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chuOPX/dJMb997GQ2N/e4GI261QLEG8BKziv1KqeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chuOPX/dJMb997GQ2N/e4GI261QLEG8BKziv1KqeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchuOPX%2FdJMb997GQ2N%2Fe4GI261QLEG8BKziv1KqeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;174&quot; height=&quot;186&quot; data-filename=&quot;je_ew.png&quot; data-origin-width=&quot;174&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_badidea.png&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caF8S6/dJMb997GQ2M/Aerk0fFcV3BRIA69cF5yd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caF8S6/dJMb997GQ2M/Aerk0fFcV3BRIA69cF5yd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caF8S6/dJMb997GQ2M/Aerk0fFcV3BRIA69cF5yd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaF8S6%2FdJMb997GQ2M%2FAerk0fFcV3BRIA69cF5yd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;186&quot; height=&quot;151&quot; data-filename=&quot;je_badidea.png&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_cry_red.png&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;950&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFyhSo/dJMcabkbE06/EoVDFJGxphqbc5sbkEq6l0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFyhSo/dJMcabkbE06/EoVDFJGxphqbc5sbkEq6l0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFyhSo/dJMcabkbE06/EoVDFJGxphqbc5sbkEq6l0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFyhSo%2FdJMcabkbE06%2FEoVDFJGxphqbc5sbkEq6l0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;848&quot; height=&quot;950&quot; data-filename=&quot;je_cry_red.png&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;950&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-12-29T15_22_11.000_lt9.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;2560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SnQVD/dJMb99Nlv3X/UVZZlZJWTjDu6zxSIqfx3K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SnQVD/dJMb99Nlv3X/UVZZlZJWTjDu6zxSIqfx3K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SnQVD/dJMb99Nlv3X/UVZZlZJWTjDu6zxSIqfx3K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSnQVD%2FdJMb99Nlv3X%2FUVZZlZJWTjDu6zxSIqfx3K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;2560&quot; data-filename=&quot;2025-12-29T15_22_11.000_lt9.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;2560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_whatdidyousay.png&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;932&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yIzEq/dJMb997GQ2T/gJYRMvILbY6Swxruwzbod0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yIzEq/dJMb997GQ2T/gJYRMvILbY6Swxruwzbod0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yIzEq/dJMb997GQ2T/gJYRMvILbY6Swxruwzbod0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyIzEq%2FdJMb997GQ2T%2FgJYRMvILbY6Swxruwzbod0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;902&quot; height=&quot;932&quot; data-filename=&quot;je_whatdidyousay.png&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;932&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_huihui.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uG8Ww/dJMcabkbE02/O7oaW9qDHwfZn6VVuKDsEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uG8Ww/dJMcabkbE02/O7oaW9qDHwfZn6VVuKDsEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uG8Ww/dJMcabkbE02/O7oaW9qDHwfZn6VVuKDsEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuG8Ww%2FdJMcabkbE02%2FO7oaW9qDHwfZn6VVuKDsEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;490&quot; data-filename=&quot;je_huihui.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_manyhalmal.png&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8VICN/dJMcabkbE0Z/XVTyCSkW64Ck1dDzGPLI90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8VICN/dJMcabkbE0Z/XVTyCSkW64Ck1dDzGPLI90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8VICN/dJMcabkbE0Z/XVTyCSkW64Ck1dDzGPLI90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8VICN%2FdJMcabkbE0Z%2FXVTyCSkW64Ck1dDzGPLI90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;310&quot; height=&quot;336&quot; data-filename=&quot;je_manyhalmal.png&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_psick.png&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKHhzd/dJMcabkbE01/ZRF7aU6Kkf8KjaKVHFj90k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKHhzd/dJMcabkbE01/ZRF7aU6Kkf8KjaKVHFj90k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKHhzd/dJMcabkbE01/ZRF7aU6Kkf8KjaKVHFj90k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKHhzd%2FdJMcabkbE01%2FZRF7aU6Kkf8KjaKVHFj90k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;480&quot; height=&quot;464&quot; data-filename=&quot;je_psick.png&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_beb.png&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OdXts/dJMb99Nlv3R/ONcryES0BKKx3Ck7kAhMok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OdXts/dJMb99Nlv3R/ONcryES0BKKx3Ck7kAhMok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OdXts/dJMb99Nlv3R/ONcryES0BKKx3Ck7kAhMok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOdXts%2FdJMb99Nlv3R%2FONcryES0BKKx3Ck7kAhMok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;464&quot; height=&quot;468&quot; data-filename=&quot;je_beb.png&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_shouting.png&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baYuZE/dJMcabkbE0Y/rvufUoTYz24h6wyh0mNW61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baYuZE/dJMcabkbE0Y/rvufUoTYz24h6wyh0mNW61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baYuZE/dJMcabkbE0Y/rvufUoTYz24h6wyh0mNW61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaYuZE%2FdJMcabkbE0Y%2FrvufUoTYz24h6wyh0mNW61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;186&quot; height=&quot;200&quot; data-filename=&quot;je_shouting.png&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_whistle.png&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;956&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPcQIP/dJMb997GQ2S/e5RhU2NMmBgJXSybmR5du1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPcQIP/dJMb997GQ2S/e5RhU2NMmBgJXSybmR5du1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPcQIP/dJMb997GQ2S/e5RhU2NMmBgJXSybmR5du1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPcQIP%2FdJMb997GQ2S%2Fe5RhU2NMmBgJXSybmR5du1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;962&quot; height=&quot;956&quot; data-filename=&quot;je_whistle.png&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;956&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_kick.png&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;842&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xRxbP/dJMcabkbE05/S7eshbt1z2dBIbKGaCkQQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xRxbP/dJMcabkbE05/S7eshbt1z2dBIbKGaCkQQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xRxbP/dJMcabkbE05/S7eshbt1z2dBIbKGaCkQQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxRxbP%2FdJMcabkbE05%2FS7eshbt1z2dBIbKGaCkQQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;984&quot; height=&quot;842&quot; data-filename=&quot;je_kick.png&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_sad.png&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBxMOq/dJMb99Nlv3U/NkAkrMmlKYTjPCEcDWWg70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBxMOq/dJMb99Nlv3U/NkAkrMmlKYTjPCEcDWWg70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBxMOq/dJMb99Nlv3U/NkAkrMmlKYTjPCEcDWWg70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBxMOq%2FdJMb99Nlv3U%2FNkAkrMmlKYTjPCEcDWWg70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;630&quot; data-filename=&quot;je_sad.png&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_sleepy.png&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sRRXc/dJMb997GQ2P/0ASrjGyRqnnLgQfihMsnpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sRRXc/dJMb997GQ2P/0ASrjGyRqnnLgQfihMsnpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sRRXc/dJMb997GQ2P/0ASrjGyRqnnLgQfihMsnpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsRRXc%2FdJMb997GQ2P%2F0ASrjGyRqnnLgQfihMsnpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;224&quot; height=&quot;246&quot; data-filename=&quot;je_sleepy.png&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_yeah.png&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4qYHH/dJMb997GQ2R/TAl49IvpZnHgkVmG4DDMtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4qYHH/dJMb997GQ2R/TAl49IvpZnHgkVmG4DDMtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4qYHH/dJMb997GQ2R/TAl49IvpZnHgkVmG4DDMtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4qYHH%2FdJMb997GQ2R%2FTAl49IvpZnHgkVmG4DDMtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;598&quot; data-filename=&quot;je_yeah.png&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;whaaaat.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0tkyu/dJMcabkbE04/tDkNJCIWd9k9WKov1BfVuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0tkyu/dJMcabkbE04/tDkNJCIWd9k9WKov1BfVuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0tkyu/dJMcabkbE04/tDkNJCIWd9k9WKov1BfVuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0tkyu%2FdJMcabkbE04%2FtDkNJCIWd9k9WKov1BfVuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;594&quot; data-filename=&quot;whaaaat.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;bruru.png&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI2q6T/dJMb99Nlv3V/FWgT8BhzkEJnihwC3aGyH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI2q6T/dJMb99Nlv3V/FWgT8BhzkEJnihwC3aGyH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI2q6T/dJMb99Nlv3V/FWgT8BhzkEJnihwC3aGyH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI2q6T%2FdJMb99Nlv3V%2FFWgT8BhzkEJnihwC3aGyH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;852&quot; height=&quot;866&quot; data-filename=&quot;bruru.png&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_yammy.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;1478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcqgGe/dJMcabkbE07/trot5Axr8UIx6F773q49D1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcqgGe/dJMcabkbE07/trot5Axr8UIx6F773q49D1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcqgGe/dJMcabkbE07/trot5Axr8UIx6F773q49D1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcqgGe%2FdJMcabkbE07%2Ftrot5Axr8UIx6F773q49D1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1102&quot; height=&quot;1478&quot; data-filename=&quot;je_yammy.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;1478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_yamyam.png&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wqRPA/dJMcabkbE00/jY8oMiLWiQbuXASk3G3We1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wqRPA/dJMcabkbE00/jY8oMiLWiQbuXASk3G3We1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wqRPA/dJMcabkbE00/jY8oMiLWiQbuXASk3G3We1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwqRPA%2FdJMcabkbE00%2FjY8oMiLWiQbuXASk3G3We1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;454&quot; data-filename=&quot;je_yamyam.png&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_sleep.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceJv0M/dJMcabkbE03/n3vWkcV11dAE88HHxY15n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceJv0M/dJMcabkbE03/n3vWkcV11dAE88HHxY15n1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceJv0M/dJMcabkbE03/n3vWkcV11dAE88HHxY15n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceJv0M%2FdJMcabkbE03%2Fn3vWkcV11dAE88HHxY15n1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;518&quot; data-filename=&quot;je_sleep.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_cry.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2gImv/dJMb99Nlv3P/kt31CgToZl3iFJHJHTFKS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2gImv/dJMb99Nlv3P/kt31CgToZl3iFJHJHTFKS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2gImv/dJMb99Nlv3P/kt31CgToZl3iFJHJHTFKS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2gImv%2FdJMb99Nlv3P%2Fkt31CgToZl3iFJHJHTFKS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;430&quot; data-filename=&quot;je_cry.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_ohoo.png&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blFcDp/dJMb997GQ2Q/tqyuwrKT9Q0tg8In6xe2V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blFcDp/dJMb997GQ2Q/tqyuwrKT9Q0tg8In6xe2V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blFcDp/dJMb997GQ2Q/tqyuwrKT9Q0tg8In6xe2V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblFcDp%2FdJMb997GQ2Q%2FtqyuwrKT9Q0tg8In6xe2V0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;542&quot; data-filename=&quot;je_ohoo.png&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_happy.png&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZumKC/dJMb99Nlv3Q/zfaAxJV5yQiBh7RbeKgkS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZumKC/dJMb99Nlv3Q/zfaAxJV5yQiBh7RbeKgkS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZumKC/dJMb99Nlv3Q/zfaAxJV5yQiBh7RbeKgkS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZumKC%2FdJMb99Nlv3Q%2FzfaAxJV5yQiBh7RbeKgkS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;420&quot; data-filename=&quot;je_happy.png&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-08 오전 9.07.06.png&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;1050&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uXydN/dJMb997GQ2U/dfEfjoyLRlF5ptiGtzr7xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uXydN/dJMb997GQ2U/dfEfjoyLRlF5ptiGtzr7xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uXydN/dJMb997GQ2U/dfEfjoyLRlF5ptiGtzr7xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuXydN%2FdJMb997GQ2U%2FdfEfjoyLRlF5ptiGtzr7xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;988&quot; height=&quot;1050&quot; data-filename=&quot;스크린샷 2026-01-08 오전 9.07.06.png&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;1050&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>육아/주은</category>
      <category>남양주시</category>
      <category>민주은</category>
      <category>황금산</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/364</guid>
      <comments>https://dotheright.tistory.com/364#entry364comment</comments>
      <pubDate>Thu, 4 Jun 2026 23:54:40 +0900</pubDate>
    </item>
    <item>
      <title>주은콘 202506 ~ 202603 - 황금산 민주은</title>
      <link>https://dotheright.tistory.com/363</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;황금산 민주은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_be.png&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uPrxZ/dJMcahYWxiN/8skGjtaGsdlOZJEKrg1w7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uPrxZ/dJMcahYWxiN/8skGjtaGsdlOZJEKrg1w7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uPrxZ/dJMcahYWxiN/8skGjtaGsdlOZJEKrg1w7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuPrxZ%2FdJMcahYWxiN%2F8skGjtaGsdlOZJEKrg1w7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;182&quot; height=&quot;185&quot; data-filename=&quot;je_be.png&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;185&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_ssuik.jpeg&quot; data-origin-width=&quot;163&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w8UTK/dJMcahdBDLY/IRMlmKfWtxlIEqLHbQjsEK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w8UTK/dJMcahdBDLY/IRMlmKfWtxlIEqLHbQjsEK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w8UTK/dJMcahdBDLY/IRMlmKfWtxlIEqLHbQjsEK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw8UTK%2FdJMcahdBDLY%2FIRMlmKfWtxlIEqLHbQjsEK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;163&quot; height=&quot;155&quot; data-filename=&quot;je_ssuik.jpeg&quot; data-origin-width=&quot;163&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_huihui2.jpeg&quot; data-origin-width=&quot;113&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVTV8m/dJMcaip1RKc/7t9rFKM0eOfbpknAYBC2b1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVTV8m/dJMcaip1RKc/7t9rFKM0eOfbpknAYBC2b1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVTV8m/dJMcaip1RKc/7t9rFKM0eOfbpknAYBC2b1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVTV8m%2FdJMcaip1RKc%2F7t9rFKM0eOfbpknAYBC2b1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;113&quot; height=&quot;110&quot; data-filename=&quot;je_huihui2.jpeg&quot; data-origin-width=&quot;113&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_omg2.jpeg&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YuwA7/dJMcaip1RKb/UjEKiMRBp0AJfugMGNZTGk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YuwA7/dJMcaip1RKb/UjEKiMRBp0AJfugMGNZTGk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YuwA7/dJMcaip1RKb/UjEKiMRBp0AJfugMGNZTGk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYuwA7%2FdJMcaip1RKb%2FUjEKiMRBp0AJfugMGNZTGk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;119&quot; height=&quot;117&quot; data-filename=&quot;je_omg2.jpeg&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_strongstrong.png&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;1238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MIXdU/dJMcacKalns/rqpMwpXACwf3ZunJRgIE1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MIXdU/dJMcacKalns/rqpMwpXACwf3ZunJRgIE1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MIXdU/dJMcacKalns/rqpMwpXACwf3ZunJRgIE1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMIXdU%2FdJMcacKalns%2FrqpMwpXACwf3ZunJRgIE1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1228&quot; height=&quot;1238&quot; data-filename=&quot;je_strongstrong.png&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;1238&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_flopdown.png&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uod5b/dJMcacKalnr/bgkw57yy0tWLVolWVqC0h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uod5b/dJMcacKalnr/bgkw57yy0tWLVolWVqC0h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uod5b/dJMcacKalnr/bgkw57yy0tWLVolWVqC0h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUod5b%2FdJMcacKalnr%2Fbgkw57yy0tWLVolWVqC0h1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;952&quot; height=&quot;766&quot; data-filename=&quot;je_flopdown.png&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_nooooo.png&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;1260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yiwzQ/dJMcahYWxiQ/ACihfu4BExKAak9kcDtSLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yiwzQ/dJMcahYWxiQ/ACihfu4BExKAak9kcDtSLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yiwzQ/dJMcahYWxiQ/ACihfu4BExKAak9kcDtSLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyiwzQ%2FdJMcahYWxiQ%2FACihfu4BExKAak9kcDtSLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1172&quot; height=&quot;1260&quot; data-filename=&quot;je_nooooo.png&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;1260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_staring.png&quot; data-origin-width=&quot;314&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGHtrt/dJMcaip1RKg/Cc4662ERZMqSqChwD052Y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGHtrt/dJMcaip1RKg/Cc4662ERZMqSqChwD052Y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGHtrt/dJMcaip1RKg/Cc4662ERZMqSqChwD052Y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGHtrt%2FdJMcaip1RKg%2FCc4662ERZMqSqChwD052Y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;314&quot; height=&quot;274&quot; data-filename=&quot;je_staring.png&quot; data-origin-width=&quot;314&quot; data-origin-height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_pressed2.png&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQ9a8C/dJMcahYWxiP/b3k2zTSfZK8VmH2uvvHHvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQ9a8C/dJMcahYWxiP/b3k2zTSfZK8VmH2uvvHHvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQ9a8C/dJMcahYWxiP/b3k2zTSfZK8VmH2uvvHHvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQ9a8C%2FdJMcahYWxiP%2Fb3k2zTSfZK8VmH2uvvHHvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;296&quot; height=&quot;314&quot; data-filename=&quot;je_pressed2.png&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_pressed.png&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/COfw1/dJMcaip1RKf/ze603nYL9RBYk5CUp8M5x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/COfw1/dJMcaip1RKf/ze603nYL9RBYk5CUp8M5x0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/COfw1/dJMcaip1RKf/ze603nYL9RBYk5CUp8M5x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCOfw1%2FdJMcaip1RKf%2Fze603nYL9RBYk5CUp8M5x0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;262&quot; height=&quot;260&quot; data-filename=&quot;je_pressed.png&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_omg_2.png&quot; data-origin-width=&quot;166&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvWRQe/dJMcaip1RKe/YqHkkqqMi6Hqnhkvr4SToK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvWRQe/dJMcaip1RKe/YqHkkqqMi6Hqnhkvr4SToK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvWRQe/dJMcaip1RKe/YqHkkqqMi6Hqnhkvr4SToK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvWRQe%2FdJMcaip1RKe%2FYqHkkqqMi6Hqnhkvr4SToK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;166&quot; height=&quot;192&quot; data-filename=&quot;je_omg_2.png&quot; data-origin-width=&quot;166&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_interesting.png&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4fcJb/dJMcacKalnp/q6R88oDB1rsqk0CmAlSsK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4fcJb/dJMcacKalnp/q6R88oDB1rsqk0CmAlSsK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4fcJb/dJMcacKalnp/q6R88oDB1rsqk0CmAlSsK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4fcJb%2FdJMcacKalnp%2Fq6R88oDB1rsqk0CmAlSsK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;328&quot; height=&quot;326&quot; data-filename=&quot;je_interesting.png&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_omg.png&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fk4AA/dJMcacKalnq/MB3FkkL5PReWYi8x6Rs3v0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fk4AA/dJMcacKalnq/MB3FkkL5PReWYi8x6Rs3v0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fk4AA/dJMcacKalnq/MB3FkkL5PReWYi8x6Rs3v0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFk4AA%2FdJMcacKalnq%2FMB3FkkL5PReWYi8x6Rs3v0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;368&quot; height=&quot;362&quot; data-filename=&quot;je_omg.png&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;je_hehe.png&quot; data-origin-width=&quot;222&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mMF6S/dJMcahYWxiO/TXADrRbSrWksRjnWz24Vvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mMF6S/dJMcahYWxiO/TXADrRbSrWksRjnWz24Vvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mMF6S/dJMcahYWxiO/TXADrRbSrWksRjnWz24Vvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmMF6S%2FdJMcahYWxiO%2FTXADrRbSrWksRjnWz24Vvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;222&quot; height=&quot;212&quot; data-filename=&quot;je_hehe.png&quot; data-origin-width=&quot;222&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>육아/주은</category>
      <category>남양주시</category>
      <category>민주은</category>
      <category>황금산</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/363</guid>
      <comments>https://dotheright.tistory.com/363#entry363comment</comments>
      <pubDate>Thu, 4 Jun 2026 23:53:45 +0900</pubDate>
    </item>
    <item>
      <title>redis cli에서 spring session 정보 확인하기</title>
      <link>https://dotheright.tistory.com/361</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;redis cli 시작&lt;/p&gt;
&lt;pre id=&quot;code_1635999065194&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// redis-cli 접근
// redis가 설치된 곳에서
$ redis-cli
// 다른 host에 접근
$ redis-cli -h {host}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키 확인&lt;/p&gt;
&lt;pre id=&quot;code_1635999496322&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 모든 키 목록
{host}:{port}&amp;gt; keys *

// 특정 키 검색
{host}:{port}&amp;gt; keys {key}
{host}:{port}&amp;gt; keys {*key} // like 검색
{host}:{port}&amp;gt; keys {key*} // like 검색

// 키의 타입 확인
{host}:{port}&amp;gt; type {key}

// spring session key 예시
// 해당 세션에 저장된 데이터들
// type : hash
spring:session:sessions:{sessionId}

// 해당 세션의 만료 키로 사용
// type : string
spring:session:sessions:expires:{sessionId}	

// expire time에 삭제될 세션 정보들 포함
// type : set
spring:session:expirations:{expireTime}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키에 담긴 정보 확인&lt;/p&gt;
&lt;pre id=&quot;code_1635999634159&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// string
{host}:{port}&amp;gt; get {key}

// hash
{host}:{port}&amp;gt; hgetall {key}

// sets
{host}:{port}&amp;gt; smembers {key}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키 만료시간 확인&lt;/p&gt;
&lt;pre id=&quot;code_1636003796441&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// spring:session:sessions:expires:{sessionId}의 만료까지 남은시간을 알 수 있다.
{host}:{port}&amp;gt; ttl {key}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\x__ 친구들의 정체...?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #1d1c1d;&quot;&gt;JdkSerializationRedisSerializer에 의해 직렬화된 byte code&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #1d1c1d;&quot;&gt;이 내용 읽고싶으면 json으로 직렬화하세요!&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1636005191070&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;\xac\xed\x00\x05sr\x00\x0e&lt;/code&gt;&lt;/pre&gt;</description>
      <category>공부/웹</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/361</guid>
      <comments>https://dotheright.tistory.com/361#entry361comment</comments>
      <pubDate>Thu, 4 Nov 2021 14:32:12 +0900</pubDate>
    </item>
    <item>
      <title>네이버 파이낸셜 코테(2021-08-28)</title>
      <link>https://dotheright.tistory.com/358</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;858&quot; data-filename=&quot;image.png&quot; width=&quot;593&quot; height=&quot;580&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hhmwp/btrdqjnadg7/QuanIq5sUvFfgMSLPLU2Ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hhmwp/btrdqjnadg7/QuanIq5sUvFfgMSLPLU2Ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hhmwp/btrdqjnadg7/QuanIq5sUvFfgMSLPLU2Ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHhmwp%2Fbtrdqjnadg7%2FQuanIq5sUvFfgMSLPLU2Ek%2Fimg.png&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;858&quot; data-filename=&quot;image.png&quot; width=&quot;593&quot; height=&quot;580&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1630227119749&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 워드 머신은 정수 스택에 대해 일련의 간단한 작업을 수행하는 시스템입니다.
// 처음에는 스택이 비어 있습니다.
// 작업 순서는 문자열로 제공됩니다. 작업은 단일 공백으로 구분됩니다.
// 아래는 예시입니다. 다음 작업을 지정할 수 있습니다.
//  - 정수 X(0~ 2^20-1) : 머신은 X를 스택에 저장합니다.
//  - POP : 머신은 스택의 최신값을 제거합니다.
//  - DUP : 머신은 스택의 최신값과 같은 값을 스택에 추가합니다.
//  - + : 머신은 스택의 최근 두 개의 값을 꺼내서 더한 결과값을 스택에 추가합니다.
//  - - : 머신은 스택의 맨 위 두 개의 값을 꺼내서 첫 번째 뺀 값에서 두 번째 것을 뺀 결과값을 스택에 추가합니다.

// 모든 작업이 수행된 후에 머신은 스택의 맨 위 값을 리턴합니다.
// 머신은 20-bit 부호없는 정수를 처리합니다.
// 덧셈의 오버플로나 뺄셈의 언더플로는 오류를 일으킵니다.
// 또한 머신은 스택에 실제로 포함된 것보다 더 많은 숫자가 스택에 있을 것으로 예상되는 작업을 수행하려고 할 때 오류를 보고합니다.
// 또한 모든 작업을 수행한 후 스택이 비어 있으면 시스템이 오류를 보고합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1630227125195&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (S.contains(&quot;aaa&quot;)) {
            return -1;
        }

        char[] chars = S.toCharArray();
        int notACount = 0;
        int currentACount = 0;
        for (char aChar : chars) {
            if ('a' != aChar) {
                notACount++;
            } else {
                currentACount ++;
            }
        }
        int totalACount = (notACount + 1) * 2;
        return totalACount - currentACount;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;884&quot; data-filename=&quot;image (1).png&quot; width=&quot;683&quot; height=&quot;739&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HhVyH/btrdykEAKdU/tzNLGtgBKi1zBZLE0i85A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HhVyH/btrdykEAKdU/tzNLGtgBKi1zBZLE0i85A1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HhVyH/btrdykEAKdU/tzNLGtgBKi1zBZLE0i85A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHhVyH%2FbtrdykEAKdU%2FtzNLGtgBKi1zBZLE0i85A1%2Fimg.png&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;884&quot; data-filename=&quot;image (1).png&quot; width=&quot;683&quot; height=&quot;739&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;917&quot; data-filename=&quot;image (2).png&quot; width=&quot;684&quot; height=&quot;623&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfplI3/btrduVSPzHo/nb0jbAfAEK7KTMfmhHhFb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfplI3/btrduVSPzHo/nb0jbAfAEK7KTMfmhHhFb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfplI3/btrduVSPzHo/nb0jbAfAEK7KTMfmhHhFb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfplI3%2FbtrduVSPzHo%2Fnb0jbAfAEK7KTMfmhHhFb0%2Fimg.png&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;917&quot; data-filename=&quot;image (2).png&quot; width=&quot;684&quot; height=&quot;623&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1630227192838&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// you can also use imports, for example:
// import java.util.*;
import java.util.*;

// you can write to stdout for debugging purposes, e.g.
// System.out.println(&quot;this is a debug message&quot;);

class Solution {
    public int solution(String S) {
        Stack&amp;lt;Integer&amp;gt; stack;
        try {
            stack = operateWordMachine(S);
        } catch (EmptyStackException | StackOverflowError | NumberFormatException e) {
            return -1;
        }
        return stack.pop();
    }

    private Stack operateWordMachine(String S) {
        Stack&amp;lt;Integer&amp;gt; stack = new Stack();
        String[] sequence = S.split(&quot; &quot;);
        for (String command : sequence) {
            switch (command) {
                case &quot;POP&quot; : stack.pop(); break;
                case &quot;DUP&quot; : stack.push(stack.peek()); break;
                case &quot;+&quot; : stack.push(stack.pop() + stack.pop()); break;
                case &quot;-&quot; : stack.push(stack.pop() - stack.pop()); break;
                default :
                    int number = Integer.parseInt(command);
                    if (number &amp;gt; 1_048_575) {
                        throw new StackOverflowError();
                    }
                    stack.push(Integer.parseInt(command));
            }
        }
        return stack;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;917&quot; data-filename=&quot;image.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ti4x8/btrdyjTcEgI/CZXib81DkxNI2TARWF1XM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ti4x8/btrdyjTcEgI/CZXib81DkxNI2TARWF1XM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ti4x8/btrdyjTcEgI/CZXib81DkxNI2TARWF1XM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTi4x8%2FbtrdyjTcEgI%2FCZXib81DkxNI2TARWF1XM0%2Fimg.png&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;917&quot; data-filename=&quot;image.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1630227237794&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// N개의 정수배열 A와 정수 K가 주어진다.
// 나머지 요소의 진폭이 최소가 되도록 A에서 K개의 연속 요소를 제거하려고 합니다.
// 진폭은 최대 요소와 최소 요소 간의 차이입니다.
// 리턴값은 A에서 K개의 연속적인 요소를 제거한 후 얻을 수 있는 최소 진폭을 나타내는 정수.

// 정수배열에서 최대값과 최소값 차이가 가장적어야함
// 그런데 이제 K만큼 연속적으로 지워야됨(중복아님)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1630227301595&quot; class=&quot;html xml&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; cursor: default; z-index: 1;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// you can also use imports, for example:
// import java.util.*;
import java.util.Arrays;
// you can write to stdout for debugging purposes, e.g.
// System.out.println(&quot;this is a debug message&quot;);

class Solution {
    public int solution(int[] A, int K) {
        int arrayLastIndex = A.length - 1;
        Arrays.sort(A);
        if (arrayLastIndex == K) {
            return 0;
        }

        int lastMinusFirst = A[arrayLastIndex] - A[0];
        int kMinusFirst = A[arrayLastIndex - K] - A[0];
        int lastMinusK = A[arrayLastIndex] - A[K];

        int[] resultCases = new int[]{lastMinusFirst, kMinusFirst, lastMinusK};
        Arrays.sort(resultCases);

        return resultCases[0];
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1630227301595&quot; class=&quot;html xml&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; cursor: default; z-index: 1;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int solution(int[] A, int K) {
    // write your code in Java SE 8
    List&amp;lt;Integer&amp;gt; list = Arrays.stream(A).boxed().collect(Collectors.toList());
    int result = getAmplitude(copyList(list));
    for (int i = 0; i &amp;lt;= list.size() - K; i++) {
        List&amp;lt;Integer&amp;gt; copyList = copyList(list);
        for (int j = i; j &amp;lt; i+K; j++) {
            copyList.remove(i);
        }
        int amplitude = getAmplitude(copyList);
        result = Math.min(result, amplitude);
    }
    System.out.println(result);
    return result;
}

private int getAmplitude(List&amp;lt;Integer&amp;gt; list) {
    Collections.sort(list);
    int amplitude = list.get(list.size() - 1) - list.get(0);
    return amplitude;
}

private List&amp;lt;Integer&amp;gt; copyList(List&amp;lt;Integer&amp;gt; list) {
    return list.stream().collect(Collectors.toList());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>공부/알고리즘</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/358</guid>
      <comments>https://dotheright.tistory.com/358#entry358comment</comments>
      <pubDate>Sun, 29 Aug 2021 17:55:10 +0900</pubDate>
    </item>
    <item>
      <title>Docker 기초 - 생활코딩</title>
      <link>https://dotheright.tistory.com/357</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 도커란?&lt;/h3&gt;
&lt;pre class=&quot;autohotkey&quot;&gt;&lt;code&gt;직역하자면 부두에서 컨테이너를 다루는 노동자를 의미.
vmware, virtualbox와 같은 가상 머신처럼 독립된 실행환경을 제공하면서도, 
컴퓨터에 직접 애플리케이션을 설치한 것과 같이 빠르고, 
apt, npm, pip 처럼 명령어 한줄로 원하는 앱이 포함된 실행환경을 손쉽게 설치할 수 있는 
환상적인 개발환경을 제공합니다. - by egoing

리눅스의 컨테이너 기술을 이용해서 프로세스만 격리해서 빠르게 실행시키는 기술
가상 운영체제의 단점인 많은 자원 소모 없이 같은 효과를 낼 수 있음&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;호스트와 컨테이너
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;호스트 : 운영체제가 설치된 컴퓨터&lt;/li&gt;
&lt;li&gt;컨테이너 : 호스트에서 실행되는 격리된 실행환경
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;운영체제가 설치되어있지 않음&lt;/li&gt;
&lt;li&gt;앱을 실행하는데 필요한 라이브러리와 실행파일만 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 이미지 pull&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;용어
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Docker Hub : App Store
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hub.docker.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;image : program&lt;/li&gt;
&lt;li&gt;container : process&lt;/li&gt;
&lt;li&gt;이미지 pull : App Store에서 프로그램을 다운로드 받는 동작에 대응&lt;/li&gt;
&lt;li&gt;이미지 run : 이미지를 실행시키는 행위. program을 실행해서 process를 만드는 동작에 대응&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UEJI4/btreJZBgDWw/pmSW8kBAE6WvseRcnV7C4k/img.png&quot; width=&quot;568&quot; height=&quot;382&quot; data-image-src=&quot;https://blog.kakaocdn.net/dn/UEJI4/btreJZBgDWw/pmSW8kBAE6WvseRcnV7C4k/img.png&quot; data-origin-width=&quot;1888&quot; data-origin-height=&quot;1270&quot; /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;396&quot; width=&quot;570&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMCgds/btreRR22AVo/4OQEktQcRZQKk9haJdviV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMCgds/btreRR22AVo/4OQEktQcRZQKk9haJdviV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMCgds/btreRR22AVo/4OQEktQcRZQKk9haJdviV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMCgds%2FbtreRR22AVo%2F4OQEktQcRZQKk9haJdviV1%2Fimg.png&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;396&quot; width=&quot;570&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 컨테이너 run&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GUI에서 run : images에 pull받은 image run&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2452&quot; data-origin-height=&quot;930&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YlCI9/btreWJJYWeP/rBidbD5xZOAKKYowBtM3g0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YlCI9/btreWJJYWeP/rBidbD5xZOAKKYowBtM3g0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YlCI9/btreWJJYWeP/rBidbD5xZOAKKYowBtM3g0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYlCI9%2FbtreWJJYWeP%2FrBidbD5xZOAKKYowBtM3g0%2Fimg.png&quot; data-origin-width=&quot;2452&quot; data-origin-height=&quot;930&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커맨드로 run&lt;/p&gt;
&lt;pre id=&quot;code_1631508709056&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// httpd image pull
docker pull httpd
// docker image 리스트 확인
docker images&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 기본적인 명령어&lt;/h3&gt;
&lt;pre id=&quot;code_1631508949088&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// docker container를 새로이 만들고 생성
docker run [image_name]
docker run --name [name] [image_name]

// docker container 중지
docker stop [name]

// docker container 시작
docker start [name]

// docker container 삭제
docker rm [name]
// docker container 강제 삭제
docker rm --force [name]

// docker image 삭제
docker rmi [image_name]

// docker container 로그 조회
docker logs [name]
// docker container 로그 실시간 조회
docker logs -f [name]

// 실행중인 docker container 목록 조회
docker ps
// 모든 docker container 목록 조회
docker ps -a&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 네트워크&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;httpd 이미지를 받아서 run 시켰을 때, 그 container는 서버로 들어오는 80포트의 요청을 처리할 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게해야하나?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포트를 연결해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ docker run --name [name] -p [host_port]:[container_port] httpd&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2446&quot; data-origin-height=&quot;1316&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ck91TO/btreRTfxMxI/nG5hqSkLxCNcaxRmQis84k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ck91TO/btreRTfxMxI/nG5hqSkLxCNcaxRmQis84k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ck91TO/btreRTfxMxI/nG5hqSkLxCNcaxRmQis84k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fck91TO%2FbtreRTfxMxI%2FnG5hqSkLxCNcaxRmQis84k%2Fimg.png&quot; data-origin-width=&quot;2446&quot; data-origin-height=&quot;1316&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. docker container 내부 조작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 조작(단일 명령어)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ docker exec [name] [command]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) docker exec ws2 pwd&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 조작(지속)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ docker exec -it [name] [command] /bin/sh&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ docker exec -it [name] [command] /bin/bash&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나가기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;# exit&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 편집툴이 없기 때문에 설치 필요 ex) # apt update #apt install nano&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 호스트와 컨테이너의 파일시스템 연결&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트의 파일시스템을 연결하지 않은 채로 컨테이너를 실행하게 된다면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너가 삭제될 때 컨테이너가 갖고있던 파일들도 모두 삭제된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ docker run -p [host_port]:[container_port] -v [host_file_path]:[container_file_path] [image_name]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) $ docker run -p 8888:80 -v ~/Desktop/htdocs:/usr/local/apache2/htdocs/ httpd&lt;/p&gt;</description>
      <category>공부/개발도구, 개발환경 등</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/357</guid>
      <comments>https://dotheright.tistory.com/357#entry357comment</comments>
      <pubDate>Sun, 22 Aug 2021 22:11:04 +0900</pubDate>
    </item>
    <item>
      <title>Spring Security(3) - form 로그인 방식 예제</title>
      <link>https://dotheright.tistory.com/356</link>
      <description>&lt;h1&gt;섹션3 실전 프로젝트&lt;/h1&gt;
&lt;h3&gt;1. 실전 프로젝트 구성&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;구성 : spring boot, spring mvc, spring data jpa, postgresql&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2. 정적 자원 접근관리&lt;/h3&gt;
&lt;p&gt;인증, 인가가 필요 없는 정적 자원에 대해서는 무시하는 설정&lt;/p&gt;
&lt;p&gt;permitAll은 필터체인을 거쳐서 무시되지만&lt;/p&gt;
&lt;p&gt;ignore는 필터체인에 들어오지도 않음&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  private final String[] IGNORED_MATCHER_PATTERNS = {&amp;quot;/static/**&amp;quot;, &amp;quot;/css/**&amp;quot;, &amp;quot;/js/**&amp;quot;, &amp;quot;/static/css/images/**&amp;quot;, &amp;quot;/webjars/**&amp;quot;, &amp;quot;/**/favicon.ico&amp;quot;};

  ...

  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(IGNORED_MATCHER_PATTERNS);
  }

}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;3. PasswordEncoder&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;비밀번호 암호화 제공&lt;/li&gt;
&lt;li&gt;기본으로는 DelegatingPasswordEncoder 클래스 사용&lt;ul&gt;
&lt;li&gt;기본 : bcrypt&lt;/li&gt;
&lt;li&gt;상황에 맞게 선택해서 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4. DB 연동 인증처리&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;UserDetailsService 등록&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;UserDetailsService 구현체 선택(UserDetailsServiceCustom)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SecurityConfig에 등록&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; @Configuration
 @EnableWebSecurity
 @RequiredArgsConstructor
 public class SecurityConfig extends WebSecurityConfigurerAdapter {

   private final UserDetailsService userDetailsService;

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
     auth.userDetailsService(userDetailsService);
   }
 }&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UserDetailsService 등록하면 뭐가되나?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용해서 UserDetails를 가져오는 loadUserByUsername 재정의&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AuthenticationProvider&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;인증 처리(비밀번호 검사 등)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; @Configuration
 @EnableWebSecurity
 public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
     // auth.userDetailsService(userDetailsService); -- authenticationProvider에서 가져오므로 더 이상 필요없음
     auth.authenticationProvider(authenticationProvider());
   }

   @Bean
   public AuthenticationProvider authenticationProvider() {
     return new AuthenticationProviderCustom();
   }
 }&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;5. 로그인 페이지, 로그아웃 커스터마이징&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;로그인 페이지&lt;ul&gt;
&lt;li&gt;SecurityConfig에 URL 등록&lt;/li&gt;
&lt;li&gt;등록한 URL 매핑(controller)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;로그아웃 커스터마이징(SecurityContextLogoutHandler)&lt;ul&gt;
&lt;li&gt;컨트롤러에서 처리&lt;/li&gt;
&lt;li&gt;SecurityContextLogoutHandler.logout()&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6. 인증 부가 기능 구현&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;WebAuthenticationDetails&lt;ul&gt;
&lt;li&gt;부가적인 정보를 사용&lt;/li&gt;
&lt;li&gt;Authentication의 Object defails로 저장됨&lt;/li&gt;
&lt;li&gt;상속받아 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AuthenticationDetailsSource&lt;ul&gt;
&lt;li&gt;WebAuthenticationDetails를 생성해주는 역할&lt;/li&gt;
&lt;li&gt;UsernamePasswordAuthenticationFilter에 setDetails메서드에서 사용(authenticationDetailsSource.buildDetails)&lt;/li&gt;
&lt;li&gt;구현체를 SecurityConfig에서 등록해서 커스터마이징 가능&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s3_1.png&quot; alt=&quot;AuthenticationDetailsSource&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AuthenticationSuccessHandler&lt;ul&gt;
&lt;li&gt;AuthenticationHandler 인터페이스 구현, 구현체 상속 등&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;// SecurityConfig
http
  ...
  .formLogin()
    ...
    .successHandler(authenticationSuccessHandler)
  ...

&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; // AuthenticationSuccessHandlerCustom
 @Component
 public class AuthenticationSuccessHandlerCustom extends SimpleUrlAuthenticationSuccessHandler {     
   private RequestCache requestCache = new HttpSessionRequestCache();     
   private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

   @Override
   public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
     setDefaultTargetUrl(&amp;quot;/&amp;quot;);
     SavedRequest savedRequest = requestCache.getRequest(request, response);
     if (savedRequest != null) {
       String targetUrl = savedRequest.getRedirectUrl();
       redirectStrategy.sendRedirect(request, response, targetUrl);
     } else {
       redirectStrategy.sendRedirect(request, response, getDefaultTargetUrl());
     }
   }     
 }
 ```&lt;/code&gt;&lt;/pre&gt;&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;p&gt;AuthenticationFailureHandler&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;인증실패 처리&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AuthenticationHandler 인터페이스 구현, 구현체 상속 등&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;// SecurityConfig
http
  ...
  .formLogin()
    ...
    .failureHandler(authenticationFailureHandler)
  ...

// AuthenticationFailureHandler
@Component
public class AuthenticationFailureHandlerCustom extends SimpleUrlAuthenticationFailureHandler {     
  @Override
  public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
    String errorMessage = &amp;quot;Invalid Username or Password&amp;quot;;
    if (exception instanceof InsufficientAuthenticationException) {
      errorMessage = &amp;quot;Invalid Secret Key&amp;quot;;
    }
    setDefaultFailureUrl(&amp;quot;/login?error=true&amp;amp;exception=&amp;quot; + errorMessage);
    super.onAuthenticationFailure(request, response, exception);
  }     
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AccessDeniedHandler&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인가예외 처리&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;@Component
public class AccessDeniedHandlerCustom implements AccessDeniedHandler {     
  @Override
  public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
    String deniedUrl = &amp;quot;/denied?message=&amp;quot; + accessDeniedException.getMessage();
    response.sendRedirect(deniedUrl);
  }     
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>공부/Spring</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/356</guid>
      <comments>https://dotheright.tistory.com/356#entry356comment</comments>
      <pubDate>Mon, 12 Jul 2021 20:28:13 +0900</pubDate>
    </item>
    <item>
      <title>Spring Security(2) - 전체 구조와 필터 별 역할 정리</title>
      <link>https://dotheright.tistory.com/355</link>
      <description>&lt;h1&gt;섹션2 스프링 시큐리티 주요 아키텍처&lt;/h1&gt;
&lt;h3&gt;1. 위임 필터 및 필터 빈 초기화 - DelegatingFilterProxy, FilterChainProxy&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;DelegatingFilterProxy&lt;ul&gt;
&lt;li&gt;ServletFilter&lt;ul&gt;
&lt;li&gt;servlet 스펙 2.3부터 도입됨. servlet으로 요청이 들어가기 전, 후에 동작&lt;/li&gt;
&lt;li&gt;servlet 컨테이너가 만들고 관리&lt;/li&gt;
&lt;li&gt;스프링에서 만든 내용을 주입받아 사용할 수 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DelegatingFilterProxy&lt;ul&gt;
&lt;li&gt;servlet 필터를 거친 요청을 Spring Bean에 위임시키는 역할&lt;/li&gt;
&lt;li&gt;servlet컨테이너가 초기화될 때 servletFilter로 등록됨&lt;/li&gt;
&lt;li&gt;ApplicationContext에서 springSecurityFilterChain을 찾아 보안처리 위임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FilterChainProxy&lt;ul&gt;
&lt;li&gt;springSecurityFilterChain이름으로 생성되는 스프링 빈&lt;/li&gt;
&lt;li&gt;스프링 시큐리티가 초기화될 때 관리할 필터들을 결정(기본필터 + 설정을 통한 추가필터)&lt;/li&gt;
&lt;li&gt;필터를 순서대로 호출해서 사용자 요청을 각각의 필터에 전달&lt;/li&gt;
&lt;li&gt;마지막 필터까지 예외가 발생하지 않으면 인증 통과&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;순서 정리&lt;blockquote&gt;
&lt;p&gt;순서&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. 서블릿 컨테이너 초기화할 때 SpringSecurity의 DelegatingFilterProxy를 서블릿 필터로 등록
2. ApplicationContext 초기화 될 때 springSecurityFilterChain 이름으로 설정된 securityFilter들을 가진 FilterChainProxy 등록
3. 서블릿 request가 들어오면 서블릿은 DelegatingFilterProxy를 통해 FilterChainProxy로 request를 보내 보안작업을 위임시킴
4. FilterChainProxy는 보안 작업을 수행
5. 보안 작업이 완료되면 서버로 요청 전달(DispatherServlet)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_1.png&quot; alt=&quot;DelegatingFilterProxy&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;서블릿 필터에서 springSecurityFilterChain이름을 찾을 수 있도록 설정하는 코드&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_2.png&quot; alt=&quot;SecurityFilterAutoConfiguration&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_3.png&quot; alt=&quot;DelegatingFilterProxy&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;스프링 컨테이너에 FilterChainProxy가 springSecurityFilterChain이름으로 등록되는 코드&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_4.png&quot; alt=&quot;SecurityFilterChain_1&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_5.png&quot; alt=&quot;SecurityFilterChain_2&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;DelegatingFilterProxy가 springSecurityFilterChain을 찾고 그 필터에게 위임하는 동작&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_6.png&quot; alt=&quot;DelegatingFilterProxyWorks_1&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_7.png&quot; alt=&quot;DelegatingFilterProxyWorks_2&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;springSecurityFilterChain이 작동(doFilterInternal메서드 안에 VertualFilterChain에서 실제 필터들이 수행됨)&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_8.png&quot; alt=&quot;FilterChainProxy&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2. 필터 초기화와 다중 보안 설정&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;다중 보안 설정&lt;ul&gt;
&lt;li&gt;2개 이상의 SecurityConfig 클래스&lt;/li&gt;
&lt;li&gt;각각의 클래스는 RequestMatcher(Request URL)로 구분하고 순서(@Order)를 설정해야 한다.&lt;/li&gt;
&lt;li&gt;설정 클래스 별로 필터체인이 생성됨&lt;/li&gt;
&lt;li&gt;동작 방식&lt;ul&gt;
&lt;li&gt;FilterChainProxy가 여러개의 SecurityFilterChain 객체를 갖는다(SecurityFilterChains)&lt;/li&gt;
&lt;li&gt;개별 SecurityFilterChain은 Filters(필터정보)와 RequestMatcher(요청정보)를 갖는다.&lt;/li&gt;
&lt;li&gt;FilterChainProxy가 요청을 받으면 요청정보에 맞는 RequestMatcher를 갖는 SecurityFilterChain으로 보안작업을 수행한다.&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_9.png&quot; alt=&quot;SecurityFilterChainMatches&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;테스트&lt;ul&gt;
&lt;li&gt;security1은 인증필요, security2는 permitAll&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;@Test
void needAuthorityConfig() throws Exception {
  ResultActions needAuthority = mockMvc.perform(get(&amp;quot;/security1&amp;quot;));
  ResultActions permitAll = mockMvc.perform(get(&amp;quot;/security2&amp;quot;));
  assertAll(() -&amp;gt; {
    needAuthority.andExpect(status().isUnauthorized());
    permitAll.andExpect(status().isOk());
  });
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_10.png&quot; alt=&quot;SecurityFilterChainMatches&quot;&gt;&lt;/li&gt;
&lt;li&gt;필터체인 선정 시점(FilterChainProxy.doFilterInternal)&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_11.png&quot; alt=&quot;SelectFilterChain&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3. Authentication(인증)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Authentication?&lt;ul&gt;
&lt;li&gt;사용자가 누구인지 증명하는 것&lt;/li&gt;
&lt;li&gt;인증 결과는 SecurityContext에 저장되어 전역적으로 참조할 수 있다.&lt;/li&gt;
&lt;li&gt;SpringSecurity에서는 interface이며 그 구현체를 인증정보를 전달하는 객체로 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Authentication 객체가 포함하는 정보&lt;pre&gt;&lt;code&gt;1. principal : 사용자 아이디 혹은 User 객체를 저장
2. credentials : 사용자 비밀번호
3. authorities : 인증된 사용자의 권한 목록
4. details : 인증 부가 정보
5. Authenticated : 인증 여부&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;SecurityContext에 저장되기 까지의 과정&lt;pre&gt;&lt;code&gt;1. UsernamePasswordAuthenticationFilter에서 Authentication 객체 생성
2. 이 때 Authentication principal은 username, credentials는 password(UsernamePasswordAuthenticationToken은 Authentication 구현체)
3. Authentication 객체 AuthenticationManager로 전달
4. 인증 후 인증객체를 갱신 : principal은 UserDetails, credentials는 null
5. 인증정보를 SecurityContextHolder(ThreadLocal)에 저장&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4. 인증 저장소 - SecurityContextHolder, SecurityContext&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;SecurityContext&lt;ul&gt;
&lt;li&gt;Authentication 객체가 저장되는 보관소&lt;/li&gt;
&lt;li&gt;언제든지 Authentication 객체를 꺼내어쓸 수 있도록 제공되는 클래스&lt;/li&gt;
&lt;li&gt;ThreadLocal에 저장되어 어디서나 참조가 가능&lt;/li&gt;
&lt;li&gt;ThreadLocal : 다른 스레드에서는 접근할 수 없는 개별 Thread의 저장소&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SecurityContextHolder&lt;ul&gt;
&lt;li&gt;SecurityContext를 갖고있는 클래스&lt;/li&gt;
&lt;li&gt;SecurityContext 저장 방식&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;1. MODE_THREADLOCAL : 하나의 스레드 당 하나의 SecurityContext 객체를 할당(default)
2. MODE_INHERITABLETHREADLOCAL : 메인 스레드와 자식 스레드에 대해 동일한 SecurityContext를 유지
3. MODE_GLOBAL : 응용 프로그램에서 단 하나의(static) SecurityContext를 갖는다.&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;인증이 완료되면 저장방식에 따라 ThreadLocal에 인증정보를 저장하고 HttpSession에 SPRING_SECURITY_CONTEXT로도 저장.&lt;/li&gt;
&lt;li&gt;인증 후에 다시 접속할 때에는 session에 저장돼있던 SecurityContext를 가져온다.&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_12.png&quot; alt=&quot;SecurityContext&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;5. SecurityContextPersistenceFilter&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;SecurityContextPersistenceFilter&lt;ul&gt;
&lt;li&gt;SecurityContext 객체의 생성, 저장, 조회 처리 역할&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;동작 순서
- 새로운 SecurityContext 생성하여 SecurityContextHolder에 저장
- 인증이 완료되면 Authentication 객체를 SecurityContext에 저장
- 익명 사용자가 아닌 경우 Session에 SecurityContext 저장
- 인증이 완료된 이후 다른 request가 들어오면 Session에서 SecurityContext를 꺼내어 SecurityContextHolder에 저장
- SecurityContext안에 Authentication 객체가 존재하면 계속 인증을 유지한다.&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;동작 코드 &lt;ul&gt;
&lt;li&gt;SecurityContext를 Session에서 가져오는데 없으면 만들어준다.&lt;/li&gt;
&lt;li&gt;finally에서 clear하고 session에 저장한다.&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_13.png&quot; alt=&quot;SecurityContextFromSession&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6. 인증 흐름 이해 AuthenticationFlow&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;인증 흐름&lt;ul&gt;
&lt;li&gt;UsernamePasswordAuthenticationFilter : 매니저로부터 받은 인증객체 SecurityContext에 저장 (AbstractAuthenticationProcessingFilter.successfulAuthentication)&lt;/li&gt;
&lt;li&gt;AuthenticationManager : 인증의 전반적인 관리(위임, 토큰 객체 생성 등), 실제 인증 역할은 AuthenticationProvider에 위임&lt;/li&gt;
&lt;li&gt;AuthenticationProvider : 실제 인증 처리, 유저 유효성 검증(패스워드 체크 등)&lt;/li&gt;
&lt;li&gt;UserDetailsService : 유저 객체 조회, UserDetails타입으로 반환&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_14.png&quot; alt=&quot;AuthenticationFlow&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;7. AuthenticationManager&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;AuthenticationManager&lt;ul&gt;
&lt;li&gt;interface이며, 기본 구현체는 ProviderManager     &lt;/li&gt;
&lt;li&gt;인증처리는 Provider에게 위임&lt;/li&gt;
&lt;li&gt;선택하는 Provider는 인증 요청에 따라 다름(Form, RememberMe, Oauth)&lt;/li&gt;
&lt;li&gt;인증 요청에 적합한 Provider가 없는 경우 parent 필드에 적합한 Provider가 있는지 탐색해서 사용&lt;/li&gt;
&lt;li&gt;적합한지 아닌지는 Provider의 supports메서드 사용&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_15.png&quot; alt=&quot;AuthenticationManager&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;초기화 과정&lt;ul&gt;
&lt;li&gt;AuthenticationManagerBuilder에서 AuthenticationProvider를 추가함&lt;/li&gt;
&lt;li&gt;여러 개를 만들어 authenticationProviders에 add&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_16.png&quot; alt=&quot;AuthenticationProviders&quot;&gt;   &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;동작&lt;ul&gt;
&lt;li&gt;초기화 과정에서 결정된 Provider에게 인증 위임&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_17.png&quot; alt=&quot;PrivoderManager&quot;&gt;&lt;/li&gt;
&lt;li&gt;적합 Provider인지 아닌지는 Provider의 supports메서드 사용해서 판단&lt;/li&gt;
&lt;li&gt;인증 객체 인스턴스 타입에 따라 선택&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_18.png&quot; alt=&quot;IsSupportsProvider&quot;&gt;&lt;/li&gt;
&lt;li&gt;작업이 완료되면 AuthenticationManager를 호출한 Filter로 인증 객체를 리턴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;8. Authorization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;인가 : 접근이 허가된 권한을 갖는 사용자인지 입증하는 절차&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;웹 계층 : URL요청에 따른 화면 단위의 보안(ex_ GET /user/id01)
서비스 계층 : 메서드 기능 단위의 보안 (ex_ public void getUserByUsername())
도메인 계층 : 객체 단위의 보안&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;FilterSecurityInterceptor&lt;ul&gt;
&lt;li&gt;필터 체인 마지막에 위치한 필터&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { ... }&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;인증된 사용자의 요청에 대해 승인/거부 여부를 최종적으로 결정&lt;/li&gt;
&lt;li&gt;권한 처리는 AccessDecisionManager에 위임&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_19.png&quot; alt=&quot;FilterSecurityInterceptor&quot;&gt;&lt;/li&gt;
&lt;li&gt;FilterSecurityInterceptor에서 super클래스의 beforeInvocation호출&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_20.png&quot; alt=&quot;FilterSecurityInterceptor&quot;&gt;&lt;/li&gt;
&lt;li&gt;beforeInvocation : 메타데이터 활용해서 인가처리(AbstractSecurityInterceptor)&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_21.png&quot; alt=&quot;AbstractSecurityInterceptor&quot;&gt;&lt;/li&gt;
&lt;li&gt;attemptAuthorization : AffirmativeBased가 인가 결정&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_22.png&quot; alt=&quot;attemptAuthorization&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;9. 인가결정 심의자&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;AccessDecisionManager&lt;ul&gt;
&lt;li&gt;사용자의 자원접근 허용여부를 최종 결정하는 주체&lt;/li&gt;
&lt;li&gt;여러 개의 Voter를 가지며 Voter들은 접근허용, 거부, 보류에 해당하는 각각의 값을 리턴한다.&lt;/li&gt;
&lt;li&gt;접근결정의 세 가지 유형&lt;ol&gt;
&lt;li&gt;AffirmativeBased : 하나라도 접근 허가면 허가 &lt;/li&gt;
&lt;li&gt;ConsensusBased : 다수표에의해 최종허가 판단. 동수일 경우 allowIfEqualGrantedDeniedDecisions옵션에 따름(default = 허가)&lt;/li&gt;
&lt;li&gt;UnanimousBased : 만장일치여야만 승인&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AccessDecisionVoter&lt;ul&gt;
&lt;li&gt;판단을 심사하는 주체&lt;/li&gt;
&lt;li&gt;권한 부여의 판단 근거가 되는 자료&lt;ol&gt;
&lt;li&gt;Authentication : 인증정보&lt;/li&gt;
&lt;li&gt;FilterInvocation : 요청정보(antManager(&amp;quot;/user&amp;quot;))&lt;/li&gt;
&lt;li&gt;ConfigAttributes : 권한정보(hasRole(&amp;quot;USER&amp;quot;))&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;구조&lt;ul&gt;
&lt;li&gt;FilterSecurityInterceptor가 AccessDecisionManager에 인가처리를 요청하면?&lt;/li&gt;
&lt;li&gt;AccessDecisionManager가 갖는 Voter들이 판단처리&lt;/li&gt;
&lt;li&gt;승인이 거부되면 ExceptionTranslationFilter가 처리&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_23.png&quot; alt=&quot;accessDecisionManager&quot;&gt;&lt;/li&gt;
&lt;li&gt;AccessDecisionVoter의 여러 구현체들&lt;br&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_24.png&quot; alt=&quot;accessDecisionVoter&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;10. 정리&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/HyeongJunMin/SpringSecurityStudy/master/src/main/resources/images/s2_25.png&quot; alt=&quot;springSecurityOverallArchitecture&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;초기화&lt;ol&gt;
&lt;li&gt;SecurityConfig 선언&lt;/li&gt;
&lt;li&gt;선언된 대로 HttpSecurity가 filter들을 생성&lt;/li&gt;
&lt;li&gt;WebSecurity가 HttpSecurity들의 filter목록을 받아 FilterChainProxy로 전달&lt;/li&gt;
&lt;li&gt;DelegatingFilterProxy가 초기화될 때 springSecurityFilterChain이라는 빈을 찾아서 요청을 위임하게됨&lt;/li&gt;
&lt;li&gt;springSecurityFilterChain빈은 FilterChainProxy&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;인증 인가 과정 : 로그인 시도 - 성공&lt;ol&gt;
&lt;li&gt;SecurityContextPersistenceFilter&lt;ul&gt;
&lt;li&gt;SecurityContext가 있는지 확인&lt;/li&gt;
&lt;li&gt;있으면 가져오고 없으면 만들어줌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LogoutFilter : 로그아웃 요청이 아니므로 패스&lt;/li&gt;
&lt;li&gt;UsernamePasswordAuthenticationFilter&lt;ul&gt;
&lt;li&gt;인증처리하고 SecurityContext에 인증객체 저장&lt;/li&gt;
&lt;li&gt;AuthenticationManager, AuthenticationProvider, UserDetailsService&lt;/li&gt;
&lt;li&gt;인증에 성공하면 SessionManagementFilter에 선언된 기능을 사용해서 후속처리&lt;/li&gt;
&lt;li&gt;LoginSuccessHandler에 따라 동작하게됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SecurityContextPersistenceFilter&lt;ul&gt;
&lt;li&gt;이 전에 로그인한 정보를 가져옴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LogoutFilter : 로그아웃 요청이 아니므로 패스&lt;/li&gt;
&lt;li&gt;UsernamePasswordAuthenticationFilter : 인증 요청이 아니므로 패스&lt;/li&gt;
&lt;li&gt;ConcurrentSessionFilter : 동시세션제어가 아니므로 패스&lt;/li&gt;
&lt;li&gt;RememverMeAuthenticationFilter : remember-me cookie 확인&lt;/li&gt;
&lt;li&gt;AnonymousAuthenticationFilter : 인증사용자이므로 패스&lt;/li&gt;
&lt;li&gt;SessionManagementFilter : 세션이 있고 세션에 인증객체도 있기 때문에 패스&lt;/li&gt;
&lt;li&gt;ExceptionTranslationFilter : 인가예외 처리&lt;/li&gt;
&lt;li&gt;FilterSecurityInterceptor : 인가처리를 하는 필터로 예외발생시킴&lt;pre&gt;&lt;code&gt;1,2,3,4 : 로그인 요청
5,6,7,8,9,10,11,12 : 자원접근 요청&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>공부/Spring</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/355</guid>
      <comments>https://dotheright.tistory.com/355#entry355comment</comments>
      <pubDate>Wed, 7 Jul 2021 09:27:43 +0900</pubDate>
    </item>
    <item>
      <title>git 원격저장소에는 없는 브랜치가 로컬에는 있어서 pull, fetch가 안될 때</title>
      <link>https://dotheright.tistory.com/354</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;원격저장소에는 분명 없는 브랜치인데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에서 pull받으려고 하면 아래처럼 오류가 나는 경우가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1625058134516&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from 원격저장소
	at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:899)
	at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1114)
	at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1145)
	at hudson.scm.SCM.checkout(SCM.java:505)
	at hudson.model.AbstractProject.checkout(AbstractProject.java:1206)
	at hudson.model.AbstractBuild$AbstractBuildExecution.defaultCheckout(AbstractBuild.java:574)
	at jenkins.scm.SCMCheckoutStrategy.checkout(SCMCheckoutStrategy.java:86)
	at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:499)
	at hudson.model.Run.execute(Run.java:1880)
	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:543)
	at hudson.model.ResourceController.execute(ResourceController.java:97)
	at hudson.model.Executor.run(Executor.java:428)
Caused by: hudson.plugins.git.GitException: Command...
error: cannot lock ref '브랜치': '브랜치' exists; cannot create '브랜치'
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2372)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandWithCredentials(CliGitAPIImpl.java:1985)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.access$500(CliGitAPIImpl.java:80)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl$1.execute(CliGitAPIImpl.java:563)
	at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:897)
	... 11 more
ERROR: Error fetching remote repo 'origin'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 땐?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ git remote prune origin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ git fetch --prune&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;끝&lt;/p&gt;</description>
      <category>공부/버전관리(Github, Gitlab...)</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/354</guid>
      <comments>https://dotheright.tistory.com/354#entry354comment</comments>
      <pubDate>Wed, 30 Jun 2021 22:00:52 +0900</pubDate>
    </item>
    <item>
      <title>Spring Security(1)</title>
      <link>https://dotheright.tistory.com/353</link>
      <description>&lt;h1&gt;섹션1 스프링 시큐리티 기본 API 및 Filter 이해&lt;/h1&gt;
&lt;h3&gt;1. spring-boot-starter-security 디펜던시를 추가하면 무슨일이 생기나&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;서버가 기동되면 스프링 시큐리티의 초기화 작업 및 기본적인 보안 설정이 이루어진다.&lt;ul&gt;
&lt;li&gt;기본적인 보안 설정?&lt;ul&gt;
&lt;li&gt;모든 요청에 대해 인증을 요구한다.&lt;/li&gt;
&lt;li&gt;인증 방식은 폼 로그인 방식과 httpBasic로그인 방식을 제공한다.&lt;/li&gt;
&lt;li&gt;기본 로그인 페이지 제공&lt;/li&gt;
&lt;li&gt;기본 계정 제공 : user / {password}&lt;pre&gt;&lt;code&gt;Using generated security password: 4add4fb7-0180-4223-8cde-a278183cb58c&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2. 사용자 정의 보안 기능 구현(Customizing)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;WebSecurityConfigurerAdapter&lt;ul&gt;
&lt;li&gt;서버가 구동되면서 이 클래스를 호출한다.&lt;/li&gt;
&lt;li&gt;스프링 시큐리티의 웹 보안 기능을 초기화하고 설정해주는 추상 클래스&lt;/li&gt;
&lt;li&gt;HttpSecurity를 생성한다.(WebSecurityConfigurerAdapter의 init메서드에서)&lt;/li&gt;
&lt;li&gt;HttpSecrity는 세부적인 보안 기능을 설정할 수 있는 API를 제공한다. 크게 인증 API, 인가 API로 나뉜다.&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;// WebSecurityConfigurerAdapter가 갖는 메서드
@Override
public void init(WebSecurity web) throws Exception {
 HttpSecurity http = getHttp();
 web.addSecurityFilterChainBuilder(http).postBuildAction(() -&amp;gt; {
   FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);
   web.securityInterceptor(securityInterceptor);
 });
}
protected final HttpSecurity getHttp() throws Exception {
 if (this.http != null) {
   return this.http;
 }
 // ... 생략
 this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects);
 // ... 생략
 return this.http;
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;커스터마이징&lt;ul&gt;
&lt;li&gt;@EnableWebSecurity 어노테이션을 custom config클래스에 선언해주어야 한다. : 웹 보안을 활성시키기 위한 어노테이션&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FormLogin custom 설정&lt;ul&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;http
    .formLogin()
      .loginPage(&amp;quot;/login&amp;quot;) // 사용자 정의 로그인 페이지
      .defaultSuccessUrl(&amp;quot;/home&amp;quot;) // 로그인 성공 후 이동 페이지
      .failureUrl(&amp;quot;/login?error=true&amp;quot;) // 로그인 실패 후 이동 페이지
      .usernameParameter(&amp;quot;username&amp;quot;) // form에 아이디 파라미터 key
      .passwordParameter(&amp;quot;password&amp;quot;) // form에 비밀번호 파라미터 key
      .loginProcessingUrl(&amp;quot;&amp;quot;) // 로그인 Form action URL
      .successHandler(loginSuccessHandler()) // 로그인 성공 후 핸들러
      .failureHandler(loginFailureHandler()) // 로그인 실패 후 핸들러&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UsernamePasswordAuthenticationFilter&lt;ul&gt;
&lt;li&gt;username과 password로 인증을 처리하는 필터&lt;/li&gt;
&lt;li&gt;AbstractAuthenticationProcessingFilter를 상속받고 있음(doFilter메서드는 부모클래스에)&lt;/li&gt;
&lt;li&gt;동작&lt;ol&gt;
&lt;li&gt;request의 요청 정보가 설정된 값(loginProcessingUrl)과 같으면 동작, 아니면 다음 필터로(chain.doFilter)&lt;/li&gt;
&lt;li&gt;Authentication 객체 생성(username + password)&lt;/li&gt;
&lt;li&gt;AuthenticationManager로 인증객체 전달(Authentication Manager 내부에 갖고있는 AuthenticationProvider 객체에 인증을 위임)&lt;/li&gt;
&lt;li&gt;ProviderManager가 provider를 찾아서 인증처리&lt;/li&gt;
&lt;li&gt;AuthenticationProvider에서 인증 실패하면 예외 발생, 성공하면 인증정보를 Authentication객체에 담아 manager로 리턴&lt;/li&gt;
&lt;li&gt;여기까지 오면 Authentication 객체는 유저 정보와 권한들을 가짐&lt;/li&gt;
&lt;li&gt;인증객체를 SecurityContext에 저장&lt;/li&gt;
&lt;li&gt;SuccessHandler 동작&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LogoutFilter&lt;ul&gt;
&lt;li&gt;로그아웃(세션 무효화, 인증토큰 삭제, 쿠키정보 삭제 등) 처리해주는 필터&lt;/li&gt;
&lt;li&gt;logoutHandler : 위 작업들을 처리해주는 핸들러. 추가 기능이 필요한 경우 커스텀 가능&lt;/li&gt;
&lt;li&gt;동작&lt;ol&gt;
&lt;li&gt;request의 요청 정보가 설정된 값(logoutUrl)과 같으면 동작, 아니면 다음 필터로(chain.doFilter)&lt;/li&gt;
&lt;li&gt;SecurityContext의 인증정보를 가져와서 로그아웃 핸들러로 보냄&lt;/li&gt;
&lt;li&gt;로그아웃 핸들러는(여러 핸들러 공존 가능) 세션 무효화, 쿠키 삭제, 인증토큰 삭제, 컨텍스트 클리어 등 동작&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RememberMeAuthenticationFilter&lt;ul&gt;
&lt;li&gt;서버가 쿠키를 발급해주고 클라이언트가 쿠키를 서버로 올렸을 때 서버는 토큰기반 인증을 사용해 검증이 되면 로그인 처리&lt;/li&gt;
&lt;li&gt;인증 성공할 때 쿠키 생성, 인증 실패 또는 로그아웃할 때 쿠키 삭제&lt;/li&gt;
&lt;li&gt;동작&lt;ol&gt;
&lt;li&gt;authentication 객체가 null일 때만 동작(null이 아니면 다음 필터로)&lt;/li&gt;
&lt;li&gt;RememberMeService에서 인증처리(구현체에 따라 remember-me 정보 메모리에 저장할지 DB에 저장할지 등 선택)&lt;/li&gt;
&lt;li&gt;토큰이 있으면 추출, 없으면 doFilter&lt;/li&gt;
&lt;li&gt;토큰을 decode해서 토큰이 서로 일치하는지, User 계정이 존재하는지를 검증하고 인증처리&lt;/li&gt;
&lt;li&gt;4단계에서 문제 있으면 예외 발생&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AnonymousAuthenticationFilter&lt;ul&gt;
&lt;li&gt;익명사용자 인증 처리 필터. Authentication 객체에 anonymousUser, ROLE_ANONYMOUS로 설정해준다.&lt;/li&gt;
&lt;li&gt;인증여부를 구현할 때 isAnonymous, isAuthenticated로 구분해서 사용한다. : AuthenticationTrustResolver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SessionManagementFilter&lt;ul&gt;
&lt;li&gt;세션 관리 필터(등록, 조회, 삭제, 이력관리, 동시세션제어, 세션고정보호, 세션생성정책결정)&lt;/li&gt;
&lt;li&gt;세션고정보호&lt;ul&gt;
&lt;li&gt;공격 시나리오 : 공격자가 사용자의 세션ID(쿠키)를 공격자의 세션 ID로 설정해서 로그인한 것 처럼 사용&lt;/li&gt;
&lt;li&gt;보호방법 : 인증할 때 마다 새 세션 ID 생성(changeSessionId)&lt;/li&gt;
&lt;li&gt;서블릿 3.1이전 : 이전 세션 값 가져와서 생성(migrateSession), 전혀 새로운 세션 생성(newSession)&lt;/li&gt;
&lt;li&gt;인증된 세션 ID를 탈취하는 공격에 대해서는 다르게 방어해야함(ex_ IP check)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;세션인증전략 순서(AuthenticationStrategy)&lt;ul&gt;
&lt;li&gt;CompositeSessionAuthenticationStrategy가 delegateStrategies로 관리한다.&lt;/li&gt;
&lt;li&gt;HttpSecurity(extends AbstractConfiguredSecurityBuilder).doBuild 에서 1~3은 init(), 4는 configure()에서 설정되기 때문에 아래와 같은 순서를 갖는다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;ConcurrentSessionControlAuthenticationStrategy : 동시세션 제어&lt;/li&gt;
&lt;li&gt;ChangeSessionIdAuthenticationStrategy : 세션고정보호(세션 발급)&lt;/li&gt;
&lt;li&gt;RegisterSessionAuthenticationStrategy : sessionRegistry에 세션정보를 등록하는 역할&lt;/li&gt;
&lt;li&gt;CsrfAuthenticationStrategy : CSRF Token 체크&lt;/li&gt;
&lt;li&gt;위 전략 외 필요에 따라 다른 것들이 더 추가될 수 있음&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ConcurrentSessionFilter&lt;ul&gt;
&lt;li&gt;동시세션 제어 필터&lt;/li&gt;
&lt;li&gt;maximumSessions 설정이 있을 때만 필터체인에 등록됨 (SessionManagementConfigurer에 maximumSessions가 null이 아닌 경우)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;권한설정과 표현식(인가)&lt;ul&gt;
&lt;li&gt;권한설정 방식&lt;ul&gt;
&lt;li&gt;선언적 방식&lt;ol&gt;
&lt;li&gt;URL : 특정 URL마다 접근권한 지정&lt;/li&gt;
&lt;li&gt;메서드 : 특정 메서드마다 접근권한 지정&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;URL 선언적 방식에서 표현식&lt;ul&gt;
&lt;li&gt;antMatchers에 URL선언은 순서를 갖는다.&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;hasRole(String role)    // configurer에서 ROLE_ 붙여줌
hasAnyRole(String... roles) // configurer에서 ROLE_ 붙여줌
hasAuthority(String authority)
hasAnyAuthority(String... authorities)
access(String attribute)    //위 표현식들이 호출하는 메서드 
hasIpAddress(String ipaddressExpression)
permitAll()
denyAll()
anonymous()     // 익명 사용자 허용
rememberMe()    // rememberMe 허용
authenticated()
fullyAuthenticated()    // rememberMe 제외하고 인증된 사용자 허용&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ExceptionTranslationFilter&lt;ul&gt;
&lt;li&gt;인증예외 처리 필터이며 FilterSecurityInterceptor가 던지는 예외를 잡아서 호출함 &lt;/li&gt;
&lt;li&gt;처리하는 예외 종류&lt;ul&gt;
&lt;li&gt;AuthenticationException : 인증 예외, AuthenticationEntryPoint 호출&lt;/li&gt;
&lt;li&gt;AccessDeniedException : 인가 예외, AccessDeniedHandler에서 예외 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HttpSessionRequestCache        &lt;ul&gt;
&lt;li&gt;인증 예외가 발생한 경우 request정보를 담고있는 객체(세션에 저장됨)&lt;/li&gt;
&lt;li&gt;ExceptionTranslationFilter에서 entryPoint.commence 메서드 호출하기 전 저장한다.(session.setAttribute)&lt;/li&gt;
&lt;li&gt;RequestCacheAwareFilter에서 가져온다&lt;/li&gt;
&lt;li&gt;인증 예외 발생 후 다시 로그인에 성공했을 때 loginSuccessHandler에서 예외 발생 당시 requestUrl로 쉽게 리다이렉트 시켜줄 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사이트 간 요청 위조(CSRF)&lt;ul&gt;
&lt;li&gt;피해자의 의도와 무관하게 공격자가 의도한 행위를 서버에 요청하게끔 만드는 공격&lt;/li&gt;
&lt;li&gt;CsrfFilter&lt;ul&gt;
&lt;li&gt;모든 요청에 랜덤하게 생성된 토큰을 http 파라미터로 요구&lt;/li&gt;
&lt;li&gt;서버가 내린 csrf 토큰과 일치하지 않으면 요청실패&lt;/li&gt;
&lt;li&gt;XSS공격과 혼용돼서 csrf토큰까지 탈취되면 의미없음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;*** 분명 Filter인데 chain.doFilter를 못찾은 경험이 있다. 그럴 땐 상속클래스를 확인해보면 된다.&lt;/p&gt;
&lt;p&gt;*** 중간에 있는 eventPublisher는 어떻게 동작하나? 필터체인 중간에 끼게할 수 있나?&lt;/p&gt;</description>
      <category>공부/Spring</category>
      <author>오피스엑소더스</author>
      <guid isPermaLink="true">https://dotheright.tistory.com/353</guid>
      <comments>https://dotheright.tistory.com/353#entry353comment</comments>
      <pubDate>Thu, 17 Jun 2021 17:01:37 +0900</pubDate>
    </item>
  </channel>
</rss>