티스토리 뷰

반응형

Photo by Markus Spiske on Unsplash

 

Go언어로 HTTP API server 만들어보려 한다.

개의 endpoint 가지는데 /signup 사용자 추가, /signin 로그인 시도에 사용한다.

포스팅의 핵심 의도는 bcrypt 알고리즘을 이용해서 안전하게 password 저장하고, 로그인을 할때에 password 맞는지 확인하는 것을 정리하는 것이기에 사용자 추가시 이미 사용중인 username인지 등등 세부적인 구현은 생략하였다.

 

Bcrypt

참고링크: https://jusths.tistory.com/158

비밀번호를 위해 특화된 해시 알고리즘중의 하나이며 가장 보편적으로 쓰이는 알고리즘이다.

비밀번호용 해시 알고리즘의 특징은, 일반적인 SHA2 등에 비해서 해싱을 일부러 느리게 하는 것이다. 이를 통해서 rainbow table 같은 공격을 방어할 있다.

 

사용자 추가하기

1. 새로운 사용자가 등록을 하려하면

2. pasword bcrypt 해싱하여 username hashed password 데이터베이스에 저장하면 된다

 

추가적으로 넣을 있는 기능들은 다음과 같은 것들이 있겠다

1. 이미 등록된 username인지 확인하기

2. password 길이나 숫자 섞어 쓰기등의 컨벤션을 만족하는지 체크하기

 

사용자 인증하기

1. 인증을 요구하는 username, password 받는다.

2. 데이터베이스에서 해당 username으로 찾는다.

3. 인증 요구 password 저장되어 있는 password 포함되어 있는 salt 붙여서 해시를 생성하여 저장되어 있는 password 비교한다.

    - 물론 작업은 go crypto/bcrypt 패키지에서 제공한다.

 

추가적으로 넣을 있는 기능들은 다음과 같은 것들이 있겠다

1. 시도 횟수 제한하기

2. 아이디, 비밀번호 찾기 기능

 

코드속 들여다보기

예제 GitHub Repo: https://github.com/nicewook/go-basic-auth

 

최소한의 코드로 endpoint를 정의하고, 서버를 시작한다

func main() {
	http.HandleFunc("/signin", Signin)
	http.HandleFunc("/signup", Signup)

	initDB()
	log.Fatal(http.ListenAndServe(":8000", nil))
}

bcrypt 패키지의 GenerateFromPassword() 함수를 이용하여 hashed password를 만든다
이때 10이 bcrypt로 생성되는 시간의 길이라고 보면 되겠다.

hashedPassword, err := bcrypt.GenerateFromPassword([]byte(creds.Password), 10) 
if err != nil {
	log.Printf("failed to GenerateFromPassword: %v", err)
	w.WriteHeader(http.StatusInternalServerError)
	return
}

bcrypt 패키지의 CompareHashAndPassword() 함수에 사용자가 입력한 비밀번호와 저장되어 있는 hashed password를 함께 넣어주면, 비교하여 결과를 내어준다. 참 쉽다!

if err := bcrypt.CompareHashAndPassword([]byte(storedPassword), []byte(creds.Password)); err != nil {
	log.Printf("incorrect password, %v", err)
	w.WriteHeader(http.StatusUnauthorized)
	return
}

참고 링크

- Link: https://www.sohamkamani.com/golang/password-authentication-and-storage/

- GitHub Repo: https://github.com/sohamkamani/go-password-auth-example

반응형
댓글
댓글쓰기 폼