[이동] HTTP 인증 시도 1

13402 단어 go

소개



'기본' HTTP 인증으로 HTTP 인증을 구현해 보겠습니다.

인증 후 세션 키를 쿠키 값으로 설정하겠습니다.

메모:
이 샘플은 단순히 "기본"인증이 작동하는 방식을 확인하기 위해 만들어졌습니다.
실제로는 보안 조치를 적용해야 합니다.

'기본' HTTP 인증



'기본' HTTP 인증은 인증을 위해 한 쌍의 ID와 비밀번호를 사용합니다.
그리고 "챌린지-응답 인증"을 기반으로 합니다.
  • [클라이언트] 보호된 리소스에 액세스
  • [서버] 클라이언트에 자격 증명이 없기 때문에、서버에서 401 상태 코드와 "WWW-Authenticate"를 반환합니다.
  • [클라이언트] 유효한 ID 및 비밀번호 전송
  • [서버] 인증이 성공하고 서버가 보호된 리소스를 반환함

  • 2. 401 상태 코드 및 "WWW-Authenticate" 반환



    처음에는 서버가 401 상태 코드를 반환할 때 웹 브라우저가 어떻게 작동하는지 살펴보겠습니다.

    main.go



    package main
    
    import (
        "log"
        "net/http"
    )
    
    func main() {
        // It only returns 401 status code now. 
        http.HandleFunc("/auth/", func(w http.ResponseWriter, r *http.Request) {
            // TODO: Validate the user authentication info
    
            // At least one "WWW-Authenticate" is required.
            // Otherwise, web browsers just show the default 401 error page.
            w.Header().Set("WWW-Authenticate", "Basic realm=\"localhost\"")
            w.WriteHeader(401)
        })
        log.Fatal(http.ListenAndServe("localhost:8083", nil))
    }
    

    결과




    4. 클라이언트 사용자 패스(ID 및 비밀번호) 가져오기



    클라이언트가 ID와 암호를 입력하면 서버는 HTTP 요청 헤더에서 가져올 수 있습니다.

    웹 브라우저는 이를 HTTP 요청 헤더에 "user-pass"로 설정합니다.
    "user-pass"는 다음 형식으로 생성되고 Base64로 인코딩됩니다.

    {ID}:{Password}
    


    웹 브라우저는 Scheme과 함께 "Authorization"키로 이를 등록합니다.

    Basic {user-pass}
    


    서버는 이를 Scheme(Basic), ID, Password로 나눌 수 있습니다.

    main.go




    ...
    import (
        "encoding/base64"
        "log"
        "net/http"
        "strings"
    )
    ...
    func signin(r *http.Request) {
        // Get user-pass
        authText := r.Header.Get("Authorization")
        splitted := strings.Split(authText, " ")
        if len(splitted) >= 2 {
            log.Printf("Authorization: %s UserPass: %s", splitted[0], splitted[1])
            decoded, err := base64.StdEncoding.DecodeString(splitted[1])
            if err == nil {
                userPass := string(decoded)
                splitTarget := strings.Index(userPass, ":")
                if splitTarget < 0 {
                    log.Println("Invalid")
                    return
                }
                userId := userPass[0:splitTarget]
                pass := userPass[splitTarget+1:]
                log.Printf("USER ID:%s Password:%s", userId, pass)
            } else {
                log.Println(err.Error())
            }
        } else {
            log.Println("Invalid")
        }    
    }
    


    결과




    Authorization: Basic UserPass: ZmZmZ2hqazpkZmdoamts
    USER ID:fffghjk Password:dfghjkl
    


    인증 정보 저장



    인증 후 자격 증명은 어떻게 보관해야 합니까?

    예를 들어 ASP.NET Core ID는 기본적으로 쿠키에 인증 정보를 등록합니다.


  • 이번에는 쿠키에 등록을 해보도록 하겠습니다.

    내 ASP.NET Core 응용 프로그램 실행에 따르면 인증 후 설정된 쿠키는 다음과 같습니다.

    Cookie: .AspNetCore.Identity.Application=CfDJ8PAT8IN6xqxGqh9UWuW_Iif6kvwPRUoA5MEVumnp6qYnZySdcFGwZhWqaznPiKtjbsiyfYLzPmyKHs_wSDYZqSp61aiv-wzRYg5zuisGsOyVpSbKrCUkxUMSTQIrXFdNeVMdb7QDQYJahbbdgjSmZc5kOAuqK8WQh1fCQ0GxbE4XrvwEDClLm-SSRyOC72Ne76uBnGRHPzuGOFXUMklWeRcRWLPEd3ZOwMkwChKkSMA7xJjHAPtCnx0LLkZJ30YmfsbRPJ6qBWiSCoq-ChVzWZLKog0mR4SLBz7K_dEbUfdfMeAi52sXiJkk8rHSaHxxDymF4KJu8-Qg6xZ4e--02xCc-dFedut7Q2NXQPXD7PXY_wV-VB0x60KRQYNc_UeZDvuZWPZi-vgICqgraMFHoynKLEQgRbmTYU6SVRb_MX920fccmtySo8y5-xZ6P_Drmko1hqNyyZKamMKxqHxXXXX
    


    쿠키에 인증 정보를 저장하기 위한 표준 사양을 찾을 수 없었기 때문에 쿠키의 키와 값이 무엇인지 스스로 결정해야 한다고 생각했습니다.

    쿠키 설정




    expiration := time.Now()
    expiration = expiration.AddDate(0, 0, 1)
    cookie := http.Cookie{Name: "WebAuthSample", Value: uuid.New().String(), Expires: expiration}
    http.SetCookie(w, &cookie)
    


    쿠키 받기




    func getAuthenticationInfo(r *http.Request) string {
        for _, c := range r.Cookies() {
            if c.Name != "WebAuthSample" {
                continue
            }
            // If the client has a valid cookie, it can retrieve the value.
            return c.String()
        }
        return ""
    }
    


    할 것



    서버 측 응용 프로그램은 인증 프로세스를 완료한 클라이언트의 ID와 쿠키 값을 유지하고 클라이언트가 보호된 리소스에 액세스할 때 인증 상태를 확인해야 합니다.

    자원


  • RFC9110 - HTTP Semantics
  • RFC7617 - The 'Basic' HTTP Authentication Scheme
  • RFC6525 - HTTP State Management Mechanism
  • HTTP authentication - HTTP | MDN
  • Using HTTP cookies - HTTP | MDN
  • base64 - encoding/base64 - Go Packages
  • uuid - github.com/google/uuid - Go Packages
  • 좋은 웹페이지 즐겨찾기