더북(TheBook)

먼저 main.go 파일에 소셜 로그인 기능을 위한 라우터를 정의한다.

▼ main.go

router.GET("/auth/:action/:provider", loginHandler)

다음으로 auth.go 파일을 생성하고 loginHandler 함수를 작성한다.

▼ auth.go

package main
 
import (
    "log"
    "net/http"
     
    "github.com/goincremental/negroni-sessions"
    "github.com/julienschmidt/httprouter"
    "github.com/stretchr/gomniauth"
    "github.com/stretchr/gomniauth/providers/google"
    "github.com/stretchr/objx"
)
 
const (
    nextPageKey     = "next_page" // 세션에 저장되는 next page의 키
    authSecurityKey = "auth_security_key"
)
 
func init() {
    // gomniauth 정보 세팅
    gomniauth.SetSecurityKey(authSecurityKey)
    gomniauth.WithProviders(
        google.New("636296155193-a9abes4mc1p81752l116qkr9do6oev3f.apps.googleusercontent.com", "EVvuy0Agv4jWflml0pvC6-vI", "http://127.0.0.1:3000/auth/callback/google"),
    )
}
 
func loginHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    action := ps.ByName("action")
    provider := ps.ByName("provider")
    s := sessions.GetSession(r)
     
    switch action {
    case "login":
        // gomniauth.Provider의 login 페이지로 이동
        p, err := gomniauth.Provider(provider)
        if err != nil {
            log.Fatalln(err)
        }
        loginUrl, err := p.GetBeginAuthURL(nil, nil)
        if err != nil {
            log.Fatalln(err)
        }
        http.Redirect(w, r, loginUrl, http.StatusFound)
        case "callback":
        // gomniauth 콜백 처리
        p, err := gomniauth.Provider(provider)
        if err != nil {
            log.Fatalln(err)
        }
        creds, err := p.CompleteAuth(objx.MustFromURLQuery(r.URL.RawQuery))
        if err != nil {
            log.Fatalln(err)
        }
         
        // 콜백 결과로부터 사용자 정보 확인
        user, err := p.GetUser(creds)
        if err != nil {
            log.Fatalln(err)
        }
         
        if err != nil {
            log.Fatalln(err)
        }
         
        u := &User{
            Uid:       user.Data().Get("id").MustStr(),
            Name:      user.Name(),
            Email:     user.Email(),
            AvatarUrl: user.AvatarURL(),
        }
         
        SetCurrentUser(r, u)
        http.Redirect(w, r, s.Get(nextPageKey).(string), http.StatusFound)
    default:
        http.Error(w, "Auth action '"+action+"' is not supported", http.StatusNotFound)
    }
}

init() 함수에서 gomniauth를 사용하기 위한 기본 정보를 등록했다.

gomniauth에 구글 프로바이더를 등록하려면 구글 개발자 콘솔(https://console.developers.google.com/start>)에서 OAuth 클라이언트 정보를 생성해야 한다. OAuth 클라이언트 정보를 생성하는 방법은 개발자 콘솔 도움말(https://support.google.com/cloud/answer/6158849)을 참고하기 바란다.

loginHandler() 함수에서는 전달된 actionprovider에 맞는 로그인 처리를 한다. login 액션이면 해당 프로바이더의 로그인 페이지로 리다이렉트하여 소셜 로그인을 한다. 소셜 로그인 페이지에서 로그인을 성공하면 callback 액션으로 연결된다. callback 액션은 callback 정보에서 사용자 정보를 확인하여 세션에 저장한다. 세션에 이동할 페이지 url(nextPageKey)가 있으면 해당 URL로 리다이렉트한다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.