얼굴 인식 로그인을 위해 개발했던 Facial-Auth-server 와 Face-AI-Server에 대해 이야기 해보자.
GuruneLee/NetCC-FacialAuthServer
GuruneLee/NetCC-FaceAIServer
얼굴인식 로그인의 API 서버. 처리하는 요청은 signin 과 signup 두 가지가 있다.
1. /signup/face
: 사진과 메타데이터를 포함한 http 요청을 받으면, 해당 요청과 함게 온 사진을 FaceAIServer에 다시 요청하여 feature-vector 를 받아온다. feature-vector 와 메타데이터를 json 파일에 저장한다.
2. /signin/face
: 똑같이, 사진과 메타데이터를 포함한 요청을 받아 FaceAIServer를 통해 feature-vector 를 받아온다. 저장되어 있는 feature-vector 에서 이름이 같은 데이터를 가져와 vector 값을 비교한다. 값이 같으면 True 값을 응답한다.
FacialAuthServer의 API 명세
사진과 메타데이터를 담아 요청을 보내는 방식으로 multipart/form-data http 요청을 택하였다. 그런데, 해당 요청을 받아 파싱하는 과정에서 mime/multipart 패키지에 'File' 멤버에는 접근 가능한 메서드가 존재했지만, 'Value' 멤버에는 접근하는 메서드가 존재하지 않아 'r.MultipartForm.Value' 이렇게 직접 접근해서 사용해야했다. 따라서 Value 값에 접근해 사용할 수 있는 'MultipartFormValue' 메서드를 만들어 golang/go 깃허브에 pr 을 시도 했다.
// MultipartFormValue returns the first value for the provided form key
// MultipartFormValue calls ParseMultipartForm and ParseForm if necessary.
func (r *Request) MultipartFormValue(key string) (multipart.File, *multipart.FileHeader, error) {
if r.MultipartForm == multipartByReader {
return nil, nil, errors.New("http: multipart handled by MultipartReader")
}
if r.MultipartForm == nil {
err := r.ParseMultipartForm(defaultMaxMemory)
if err != nil {
return nil, nil, err
}
}
if r.MultipartForm != nil && r.MultipartForm.Value != nil {
if vhs := r.MultipartForm.Value[key]; len(fhs) > 0 {
v, err := vhs[0].Open()
return f, vhs[0], err
}
}
return nil, nil, ErrMissingValue
}
그런데... 그 때 관절이 찢어져 병원에 입원하게 되어서 답변을 한 달 넘게 안했는데, 다음부터는 respectful 한 방식으로 문의 해달라고 혼나고, 다른 api 를 통해 접근 가능한 사안이라며 반려됐다...
요청받은 이미지에서 feature-vector를 뽑아서 응답해주는 서버