Skip to content

Backend bank server based on Gin framework with auto-configuring AWS and K8S.

Notifications You must be signed in to change notification settings

ghkdqhrbals/golang-backend-master

Repository files navigation

GitHub Workflow Status (branch) GoDoc Coverage Status packagecloud.io Docker Pulls Supported Go Versions GitHub Release Go Report Card

Versions

Version Skills Done?
v1.1 Postresq, migration, Testing_enviroments, Sqlc, Git-Workflow
v1.2 Gin, Viper, Gomock, Postresq, migration, Testing_enviroments, Sqlc, Git-Workflow
v1.3 Bcrypt, Gin, Viper, Gomock, Postresq, migration, Testing_enviroments, Sqlc, Git-Workflow
v1.4 Logger, NGINX, Kubernetes, AWS, JQ, Docker, JWT, PASETO, Bcrypt, Gin, Viper, Gomock, Postresq, migration, Testing_enviroments, Sqlc, Git-Workflow

Overview

How can we automatically deploy our service?

Alt text example

We use AWS with following service

Alt text

How can we safely store user password in RDS?

Alt text

How can we handle multiple api request with asynchronous response?

Alt text

All Details and Studies in wiki

Update[v1.4.4]

  • Kubernetes Cluster 설정
  1. Set aws-ath.yaml to access AWS-EKS(with granted user)
  2. Set deployment.yaml to get image from AWS-ECR and run with 2 replica(pod)
  3. Set issuer.yaml to issue TLS certificate
    • get certificate from 'letsencrypt' with domain 'api.hwangbogyumin.com'(free)
  4. Set ingress.yaml with Nginx ingress controller
    • request -> api.hwangbogyumin.com
    • api.hwangbogyumin.com -> aws-route-53 my arn
    • aws-route-53 my arn -> nginx-ingress address
    • nginx-ingress address -> ingress-service(TLS)
    • ingress-service ->> server pods(1,2)
  • AWS-Route-53에서 Domain 생성 및 Kubernetes Ingress-service pods 연결

Update[v1.4.3]

  • Github action으로 자동 AWS docker image upload
  1. Set Configure AWS credentials
  2. Add AWS_ACCESS_KEY_ID, KEY in Github Repositry secrets
    • AWS-IAM secrets:AWS_ACCESS_KEY_ID, AWS_ACCESS_KEY
  3. Launch deploy action
    • Get secrets from Git and Access with token
    • Login
    • build images and Deploy to AWS-ECR ap-northeast-2
  • AWS-ECR, AWS-Secrets Manager, AWS-IAM, AWS-RDS 추가
  1. Secrets Manager로 Paseto의 Payload를 encrypt/decrypt하는 symmetric_key 및 RDS port, RDS root, key 관리
  2. Set IAM(Identity and Access Management) for safe AWS resource access
  3. Set ECR(Elastic Container Registry) in ap-northeast-2
  4. Set RDS(Relational Database Storage) in us-west-1, postgres12
  • JQ
  1. Get RDS informations and etc. from AWS secrets manager
  2. Transform AWS secrets format into JSON format using JQ
  3. Based on json data, set app.env with corresponding data

Update[v1.4.2]

  • Dockerfile & Docker-compose 수정
  1. Set shell script(wait-for-it.sh) to wait until postgres is readyDetail
    • As we alpine image, 'apk add bash' needed
  2. Set shell script(start.sh) to migrate db up
  3. Edit Dockerfile to add needed files
    • migrate, app.env, main(object file), pre-setting shell script(wait-for-it.sh, start.sh)
  4. Make docker-compose.yaml to specify services name and environment variables

Update[v1.4.1]

  • Token Authentication Middleware 추가
  1. Set user.go/loginUser for create/verify TOKEN
  2. Set Route(createAccounts, transferMoney, etc.) Group that need authorization.
  3. Make authMiddleware for pre-check requests whether they have TOKEN for authorization
  4. Edit api/server.go
    • Before get request, check and verify http header's authorized part.
    • If there is a TOKEN that server created, pass request to actual handler.
    • If no TOKEN exists, abort session and send response.
  5. 위의 http통신은 TLS로 encrypt되었음을 가정한다. TLS Details
    • TLS가 적용되지 않았으면 TOKEN가 탈취되었을 때, Server에 권한없이 RPC 통신하여 DB 탐색가능.
  • Testcase정의
1. User -----      Login       --> Server    [LoginParams] = username, password
2. User <----      TOKEN       --- Server    [TOKEN] = chacha20poly1305(nonce, Server's Key, AEAD, Payload{username, duration})
3. User -----    CreateAccount --> Server    [Params] = currency, TOKEN
4. User <----  Account's Info  --- Server    [Account] = verifyToken(Server's Key, TOKEN)

Update[v1.4.0]

  • JWT(JSON Web Token)의 HMAC-SHA256(HS256) algorithm를 통한 payload+header 'Encryption' and 'MAC' 생성
  1. Set secretKey as random 256 bits(As we use HS256, Key should be 256 bits) Temporary!
  2. Make CreateToken function(interface)
    • ( [HEADER]:'alg:HS256,typ:jwt', [PAYLOAD]:'id:string, name:string, expiredAt:time', [SIGNATURE]:'HMAC([HEADER],[PAYLOAD]).TAG' )
  3. Make VerifyToken function(interface)
    • Check HEADER, SIGNATURE, ...
  4. Set test enviroments
    • case Invalid Header algorithm, MAC failed, Expiration, etc.
  • PASETO(Platform-Agnostic Security Tokens)의 chacha20Poly1305 algorithm를 통한 payload+header+nonce 'Encryption' and 'MAC' 생성
  1. Set secretKey as random 256 bits(As we use chacha20Poly1305, Key should be 256 bits) Temporary!
  2. Make CreateToken function(interface)
  3. Make VerifyToken function(interface)
  4. Set test env.

Update[v1.3.1]

  • User password의 Testcases 정의
  1. Set api/user_test.go TestCreateUserAPI test function
    • cases: "OK", "InternalError", "DuplicateUsername", "InvalidUsername", "InvalidEmail", "TooShortPassword"
  2. Set Custom reply matcher(gomock)

Update[v1.3.0]

  • Bcrypt로 사용자 PW 저장(Blowfish encryption algorithm)(Detail)
  1. Set util/password.go using bcrypt which can randomly generate cost, salt to get hashed password with params
  2. Set util/password_test.go for testing
  3. Make api/user.go to set createUser handler
  4. Set routes("/user") for request from clients

Update History

  • Gin으로 RPC 통신 추가 (Details)
  1. Set router, routes
  2. Set various handler
  3. Get http request
  4. Use custom validator to check if it is a valid request.
  5. Binding JSON to STRUCT(request)
  6. Access Local Database -> Execute transactions -> Get results(all process can handle with error)
  7. Response
  • Viper으로 configuration 자동설정 (Details)
  1. Set /app.env
  2. Set /util/config.go
  3. import configurations in /main.go
  • Gomock으로 서비스 레이어의 테스트에서 DB 의존성을 제거 (Details)
  1. Use sqlc interface with all query functions to interface
  2. Edit /.bash_profile for PATH to go/bin(to using mockgen)
  3. Execute mockgen to generate mock functions
  4. Set APIs for testing(TestGetAccountAPI)

Notes