더북(TheBook)

9.3.3 인증

요청이 들어올 때마다 현재 접속한 사용자가 로그인했는지 확인하여 로그인을 안 했으면 로그인 페이지로 이동하는 기능을 작성해 보자.

negroninegroni.HandlerFunc 타입 함수를 미들웨어 핸들러로 등록할 수 있다.

▼ negroni.HandlerFunc

type HandlerFunc func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)

요청이 들어올 때마다 접속한 사용자가 로그인했는지 세션에서 확인하는 기능을 negroni.HandlerFunc 타입의 함수로 작성해 보자.

▼ auth.go

func LoginRequired(ignore ...string) negroni.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
        // ignore url이면 다음 핸들러 실행
        for _, s := range ignore {
            if strings.HasPrefix(r.URL.Path, s) {
                next(w, r)
                return
            }
        }
        // CurrentUser 정보를 가져옴
        u := GetCurrentUser(r)
                                 
        // CurrentUser 정보가 유효하면 만료 시간을 갱신하고 다음 핸들러 실행
        if u != nil && u.Valid() {
            SetCurrentUser(r, u)
            next(w, r)
            return
        }
                                 
        // CurrentUser 정보가 유효하지 않으면 CurrentUser를 nil로 세팅
        SetCurrentUser(r, nil)
                                 
        // 로그인 후 이동할 url을 세션에 저장(r)
        sessions.GetSession(r).Set(nextPageKey, r.URL.RequestURI())
                                 
        // 로그인 페이지로 리다이렉트
        http.Redirect(w, r, "/login", http.StatusFound)
    }
}

LoginRequired() 함수에서는 negroni.HandlerFunc 타입으로 핸들러 함수를 만들어 반환한다. LoginRequired() 핸들러에서는 다음과 같은 작업을 처리한다.

1. 현재 세션에서 CurrentUser 정보를 가져온다.

2. CurrentUser 정보가 유효하면 만료 시간을 갱신하고 다음 핸들러를 실행한다.

3. CurrentUser 정보가 유효하지 않으면 현재 URL을 세션에 저장하고 로그인 페이지로 리다이렉트한다. 로그인을 성공하면 세션에 저장한 URL로 다시 리다이렉트한다.

하지만 모든 URL에 대해 인증 처리를 해야 하는 건 아니다. 로그인 페이지를 비롯한 몇몇 페이지는 로그인하지 않은 사용자에게도 허용돼야 한다. 모든 사용자에게 허용된 페이지는 LoginRequired() 함수를 실행할 때 ignore 매개변수로 전달한다. 핸들러 내부에서는 요청 URL이 ignore 목록에 포함돼 있으면 인증 과정을 거치지 않고 바로 다음 핸들러로 제어권을 넘긴다.

main.go 파일에서 LoginRequired() 핸들러를 negroni에 등록하는 코드를 추가해 보자.

n.Use(LoginRequired("/login", "/auth"))

LoginRequired() 핸들러를 negroni에 등록하여 모든 요청을 인증 처리하게 했다. 단, /login과 /auth로 시작하는 URL이면 인증 처리를 하지 않는다.

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