프로그래머스 로그인 페이지

프로그래머스에 들아가서 로그인 버튼을 누르면, 위와 같은 화면이 나온다.

저기서 만약 Github으로 계속하기 버튼을 누른다면, Github 로그인 페이지로 이동하게 된다.

그리고 그곳에서 Github 로그인을 하면 프로그래머스 서비스를 이용할 수 있게 된다.

 

나는 분명 Github 로그인을 했는데 왜 프로그래머스 서비스를 이용할 수 있는 걸까?

이것에 대해 알려면 OAuth를 알아야 한다.


OAuth란?

로그인을 제공하는 플랫폼(Github)의 계정만 있다면 외부 서비스(프로그래머스) 에서도 인증을 가능하게 하여 API를 사용할 수 있도록 해주는 프로토콜이다. 그렇기 때문에 Github 로그인을 했는데도 프로그래머스의 서비스를 사용할 수 있게 된 것이다.

 

OAuth가 무엇인지 알았다면 이제 OAuth의 인증 절차에 대해 알아보자


OAuth 인증 방식

용어 정리

Resource Owner Resource Server의 계정을 소유하고 있는 사용자 ex) User
Client OAuth를 이용해 서비스를 제공하는 앱 ex) 프로그래머스, 내가 개발하고 싶은 앱
Authorization Server 토큰을 발급해주는 서비스 ex) Github 로그인 기능
Resource Server Resource Owner의 자원을 관리하는 서버 ex) Github

인증 절차

  1. Resource Owner가 Authorization Server에서 보내준 Github 로그인 페이지에 ID/PW 정보를 입력한다.
  2. Authroization Server Authorization CodeRedirect URL에 결합시켜 헤더에 담아 Resource Owner에게 전달한다.
  3. Resource OwnerRedirect URL에 리다이렉트하면 Client Client ID , Client Secret , code, Redirect URL 정보를 Authroization Server에게 전달해 Access Token 발급 요청을 한다.
  4. Access Token이 발급되었다면 Resource Owner에게 전달하며 로그인을 성공시킨다

리소스 요청

이후에 Resource OwnerClient에게 요청할 때마다 Access Token을 요청에 포함시킨다.

'Network' 카테고리의 다른 글

[Network] OSI 7 계층은 대충 이런거다  (0) 2021.04.19
[Network] TCP 3 Way Handshake란?  (0) 2021.04.02

TCP는 UDP와 달리 정확하게 데이터가 전달되어야 하는 통신이다. 그렇기 때문에 클라이언트와 서버간의 확인 절차가 존재하는데, 그 방법 중에 3 Way Handshake가 있다.

 

동작 방식

SYN = Synchronize sequence number(요청), ACK = Acknowledgement(수락)

 

1. Client -> Server

- Client가 Server로 연결 요청 메세지 SYN(1044)를 보낸다.

2. Server -> Client

- Server가 Client로 클라이언트의 요청을 수락 ACK(1044 + 1)한다.

  -> Server는 연결이 확립된다. (Established)

- Server가 Client로 연결 요청 SYN(4812)를 보낸다.

3. Client -> Server

- Client가 Server로 서버의 요청을 수락 ACK(4812 + 1)한다.

  -> Client도 연결이 확립된다. (Established)

 

🤔 왜 SYN에 +1을 해서 보낼까?

SYN + 1 한 값이 수신자가 예상하고 있는 값이기 때문이다.

이게 무슨 의미이냐면, 1044를 보내고 1045를 기다리는 것이다.

만약 1045가 아닌 다른 값이 도착한다면 연결을 하지 않을 것이다.

링크 참고

 

Why does TCP's three-way handshake bump the sequence number when acking?

Why does the TCP three-way handshake bump the sequence number when acking during the initial handshake? How is that better than just leaving the acknowledgement number equal to the sequence number...

stackoverflow.com

 

2 Way Handshake는 왜 안 되는거지?

단순히 서버와 클라이언트가 서로의 존재를 알리기 위해서는 2번의 과정만으로 충분하다고 생각할 수도 있다. 아래 그림을 보자

TCP 통신은 양방향성을 띠고 있는 통신이다. Client와 Server가 모두 존재를 알리고 패킷을 보내고 받을 수 있다는 것을 서로에게 알려야 한다.

 

만약 위와 같이 2 way handshake를 한다면,

  1. ClientServer에게 연결 요청을 한다.

  2. Server는 그것에 대한 응답을 한다. -> Client의 연결 확립 (Established)

이런 흐름이 될 것이다.

 

이게 그냥 보기에는 문제가 없어보인다. 하지만 한가지 가정을 들어보자.

만약 1번 과정이 매우 오래전에 일어났던 일이라 Client가 비가용 상태에 돌입했다면 Server는 아무것도 모르고 세션을 확립할 것이다.

그렇기 때문에 마지막에 ClientServer에게 "나는 가용 상태이다" 라는 사실을 알려줘야 한다.

'Network' 카테고리의 다른 글

[Network] OSI 7 계층은 대충 이런거다  (0) 2021.04.19
[Network] OAuth란?  (0) 2021.04.02

HTTPSSSL(Secure Socket Layer)을 이용한 HTTP 통신 방식을 의미한다. 이런 HTTPS를 아파치를 이용해 웹서버에 적용시켜보자.

 

https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html#letsencrypt

 

자습서: Amazon Linux 2에서 SSL/TLS 구성 - Amazon Elastic Compute Cloud

여러 가지 방법으로 새 인증서를 EC2 인스턴스에 업로드할 수 있지만, 가장 간편하고 유익한 방법은 텍스트 편집기(예: vi, nano, 메모장)를 로컬 컴퓨터와 인스턴스에 모두 열고 두 편집기 간에 파

docs.aws.amazon.com

위 자습서를 보고 따라해 볼 것이다.

 

1. 아파치 설치

일단 putty나 ssh등 각자만의 방법을 이용해서 인스턴스에 접속해주자

나는 Amazon Linux 2 이미지를 사용한다.

sudo yum update -y
sudo yum install -y httpd
sudo systemctl enable httpd
sudo systemctl restart httpd

위의 명령어를 차례대로 입력하면 아파치가 설치 된다.

 

제대로 설치되었는지 인스턴스 주소를 브라우저에 입력해 확인해 보자.

위와 같은 화면이 나오면 아파치가 제대로 설치 된 것이다!

 

만약, 연결이 거부되었다고 표시된다면, 보안 그룹에서 인바운드 규칙을 제대로 설정했는지 확인해 보자

나중을 위해서 https도 열어주자

2. HTTPS 적용

docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html#letsencrypt

 

자습서: Amazon Linux 2에서 SSL/TLS 구성 - Amazon Elastic Compute Cloud

여러 가지 방법으로 사용자 지정 키를 EC2 인스턴스에 업로드할 수 있지만, 가장 간편하고 유익한 방법은 텍스트 편집기(예: vi, nano, 메모장)를 로컬 컴퓨터와 인스턴스에 모두 열고 두 편집기 간

docs.aws.amazon.com

를 참고해서 하자. 자세한 설명은 후에 추가

'AWS' 카테고리의 다른 글

[AWS] 클라우드 컴퓨팅이란  (0) 2021.04.06
[AWS] AWS 서비스 정리 - Database Service  (0) 2021.04.05
[AWS] AWS 서비스 정리 - Storage Service  (0) 2021.04.05
[AWS] AWS 서비스 정리 - Computing Service  (0) 2021.04.04
[AWS] S3 정리  (0) 2021.03.26

Bucket

  • 버킷 이름은 AWS 전체에서 유니크 해야한다.
  • Region을 선택해서 어떤 지역에서 배포할 지 정할 수 있음

Block Public Access settings for bucket

  • Block all public access 옵션이 켜져 있으면 권한을 줄 때 오류가 날 수 있음

Objects

S3 URI

  • 엔드포인트 주소 (아마존 CLI를 통해서 파일을 다운 받을 때 사용함)
  • ex) aws s3 cp s3://hanbin-test-s3/asdf.txt .→ 거꾸로 하면 업로드가 됨
  • → s3://hanbin-test-s3/asdf.txt 를 . 으로 다운로드해라.

Object URL

  • 파일에 접근 할 수 있는 URL 주소
  • https://0313-s3.s3-ap-northeast-1.amazonaws.com/index.html
  • 그냥 접속하면 권한이 없다고 접근에 불가능한다고 한다.(버킷의 Block all public access 를 해제해야 함)
    • → make public 을 해주면 접근 할 수 있으나, 자주 사용하지 않는다.

Presigned URL

  • 시간이 지나면 만료가 되는 엑세스키를 포함한 미리 서명이 된 URL을 만드는 것이다.
  • 기간을 정해둔 다운로드 링크를 만들거나 할 때 사용할 수 있다.

Versioning

  • 만약 index.html 라는 이름이 같은 두개의 파일을 모두 S3에 올렸다면 전에 있던 index.html 를 덮어쓰게 되버려 이전의 파일이 사라지게 된다.
  • 이를 방지하기 위해 Bucket Versioning이 존재한다.

  • Bucket Versioning을 활성화 시키면 위와 같이 전 파일이 사라지지 않고 수정했던 시간과 함께 나오게 된다
  • 하지면 옛날 버전의 용량을 모두 계산해서 비용이 청구된다.

Default Encryption

  • 암호화 할 것인지 정함

Server Access logging

  • 어떤 ip가 어떤 resource에 접근했는지 로그를 남겨줌

Event Notification

  • 어떤 오브젝트의 이벤트를 캐치해서 그거에 맞는 이벤트를 발생 시킬 수 있다.

ex) 파일이 올라오면 그 파일에 대한 서브넷을 만들어줌

  1. 만약 사용자가 S3에 큰 용량의 이미지 파일을 업로드함
  2. lambda가 이미지 용량을 줄인다.
  3. 조정한 이미지를 따로 모아둔다.

Transfer Acceleration

  • 남미에 있는 사람이 도쿄로 이미지를 업로드하면 시간이 오래 걸린다.
  • 아마존의 전세계 네트워크를 통해서 속도를 빠르게 해준다.

Requester pays

  • 다른 아마존 계정을 가진 유저가 S3에 오브젝트 요청을 보낼 때, 요청을 보낸 유저가 요금을 지불하는 방식

With Route 53

  • 만약 S3 버킷을 Route 53으로 호스팅 하고 싶으면 Record name과 버킷의 이름이 동일해야함 ex) s3.hanbin.awscloud.work
  • 만약 ec2 인스턴스가 동작하고 있지 않을 때 같은 도메인을 띄워 오류 메세지를 띄울 수 있다.

Bucket Policy

{
	"Version" : "2012-10-17",
	"Statement" : [
		{
			"Sid" : "IPAllow",
			"Effect" : "Deny",
			"Principal" : "*",
			"Action" : ["s3:GetObject", "s3:GetObjectVersion"]
			"Resource" : [
				"arn:aws:s3:::DOC-EXAMPLE-BUCKET",
			],
			"Condition": {
				"NotIpAddress" : {"aws:SourceIp": "54.240.143.0/24"}
			}
		}
	]
}

 

CORS

  • example.com이라는 도메인에서 S3에 요청을 보낼 때 허가되지 않는 도메인 또는 메소드 라면 CORS 오류 가 발생한다.
<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>http://www.example.com</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>

위와 같이 허가를 해줄 수 있다.

Lifecycle rule

  • 생성 후 90일이 지나면 가장 싼 storage class로 바꾸는 규칙 등 아래의 규칙들을 추가할 수 있다.

Replication rule

  • 한 버킷에서 다른 버킷으로 복사할 수 있다.
    • 백업 용도로 사용할 수 있다.
    • 나는 서울 리전에 S3 버킷을 가지고 있는데 미국에 더 빠르게 데이터를 전송하기 위해서 사용할 수 있다.

VPC endpoint

  • NAT Gateway도 없고 Internet Gateway 도 없는 ec2 인스턴스가 s3 버킷에 접근할 수 있는 방법
  • 실제로 많이 사용한다고 한다.

프로젝트를 진행하면서 변경사항이 없어도 계속 makemigrations가 가능해 migration 파일이 계속 생성되는 오류가 발생했다.

 

이유를 생각해 보니 role 필드의 choices 옵션이 떠올랐다.

ROLE_CHOICES = {  # <- set!
        (STUDENT, "student"),
        (TEACHER, "teacher"),
        (ADMIN, "admin"),
}

role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES)

위와 같이 ROLE_CHOICES를 set 자료형으로 만들었는데, 파이썬의 set 자료형은 순서가 존재하지 않는다.

migrations/0001_initial.py

그래서 migration 파일을 보면 status의 choices 옵션이 makemigrations 할때마다 이것만 바뀐 파일이 생성되는 것을 알 수 있다.

 

결론은 set 자료형이 아닌 tuple 혹은 list 자료형을 사용해주면 된다

ROLE_CHOICES = (  # <- tuple!
        (STUDENT, "student"),
        (TEACHER, "teacher"),
        (ADMIN, "admin"),
)

role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES)

이동욱 저자님의 "스프링 부트와 AWS로 혼자 구현하는 웹서비스" 책을 보면서 travis ci로 자동 배포를 테스트 해보는 도중 변경사항이 적용이 되지 않았다.

travis ci 모니터링 텝에서도 오류가 잡히지 않아 무엇이 문제인지 직접 찾아야 했다.

오류 하나에 수많은 배포의 흔적... (테스트는 잘 통과함)

그래서 직접 EC2 인스턴스에 접근해서 ps 명령어를 사용해 프로세스를 확인해 봤다.

cmd 이름이 java네...?

위와 같이 나오는 것을 보고 뭔가 이상한거 같아서 deploy.sh 파일을 확인해 봤다.

이름이 jar인 프로세스를 찾아서 지우는 거네..

프로세스 이름은 java인데 jar인 프로세스를 검색해서 지우니까 기존에 돌아가던 프로세스가 중지되지 않아서 생긴 문제였다.

프로세스가 중지가 되지 않으니까 포트도 충졸한 것 같다. (nohup.out 로그를 보면 자세히 확인 할 수 있다.)

 

jar를 java로 바꿔서 해결해주자!

 

해결!

 

EC2 인스턴스에서 Spring boot jar을 실행하자 There is insufficient memory for the Java Runtime Environment to continue. 라는 에러가 검출되었다.

 

충분한 메모리가 확보되지 않았다는 것인데, 순간 떠올린 방법은 두가지였다

1. EC2의 메모리를 확장시킨다 (t3.micro 보다 큰)

2. -Xmx 와 같은 옵션으로 메모리를 직접 할당해준다.

 

1번은 돈이 나가기 때문에 포기했고, 2번을 하려고 했을때, 이전에 실행해둔 프로세스가 생각이 나서 출력을 해보았다.

> ps aux

알고보니 이전에 실행해둔 프로세스 때문에 메모리가 부족한 것이었다. 그래서 ec2 인스턴스를 재부팅 해서 해결했다.

클라우드 기능반 과제 중에서 Bastion Host에 접속해서 private subnet에 접속하는 과제가 있었다. 그런데 클라이언트에서 바스천 호스트로 퍼블릭 키 파일(.pem)를 전달할 때 오류가 발견되었다.

root@0.0.0.0 : ~# scp ./hanbin.pem ec2-user@1.2.3.4:/home/
Permission denied (publickey,gssapi-keyex,gssapi-with-mic) 

 

해결 과정 #1

검색을 해보니

https://serverfault.com/questions/598058/ssh-permission-denied-publickey-gssapi-with-mic-password

 

SSH: Permission denied (publickey,gssapi-with-mic,password)

==================================================================== UPDATE: It turned out the configuration of sshd on host2 wont allow password login. Thanks to people answered this. =========...

serverfault.com

파일 권한을 변경해주라고 하는데 내 경우에는 해결이 되지 않았다.

 

해결 과정 #2

root@0.0.0.0 : ~# scp -i hanbin.pem ./hanbin.pem ec2-user@1.2.3.4:/home/ec2-user/
Permission denied (publickey,gssapi-keyex,gssapi-with-mic) 

혹시나 해서 identify file(.pem)도 명시해주고 /home/ 경로가 아닌 유저 경로 /home/ec2-user/로 지정해 줬더니 됐다.

 

내 생각에는 ssh-add 설정을 잘못 해주어서 RSA Host key를 읽지 못했던 것 같다.

문제가 해결된 이유는

1. 직접 identify file을 명시했음

 

2. <유저 이름>@<ip 주소>:<경로> 에서 유저(ec2-user)의 권한에 맞는 경로(/home/ec2-user)를 지정해 주니 됐음

 

+ Recent posts