goweb - 폼

양식
로그 인 인터페이스 를 간단하게 처리 합 니 다.
package main

import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "strings"
)

func sayhelloName(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()       //  url     ,  POST         (request body)
    //  :      ParseForm  ,           
    fmt.Println(r.Form) //                 
    fmt.Println("path", r.URL.Path)
    fmt.Println("scheme", r.URL.Scheme)
    fmt.Println(r.Form["url_long"])
    for k, v := range r.Form {
        fmt.Println("key:", k)
        fmt.Println("val:", strings.Join(v, ""))
    }
    fmt.Fprintf(w, "Hello astaxie!") //     w         
}

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method) //       
    if r.Method == "GET" {
        t, _ := template.ParseFiles("login.gtpl")
        log.Println(t.Execute(w, nil))
    } else {
        //        ,           
        fmt.Println("username:", r.Form["username"])
        fmt.Println("password:", r.Form["password"])
    }
}

func main() {
    http.HandleFunc("/", sayhelloName)       //       
    http.HandleFunc("/login", login)         //       
    err := http.ListenAndServe(":9090", nil) //       
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

request. Form 은 url. Values 형식 으로 key = value 와 유사 한 정 보 를 저장 하고 있 습 니 다. 다음은 form 데이터 에 대한 작업 을 보 여 줍 니 다.
v := url.Values{}
v.Set("name", "Ava")
v.Add("friend", "Jess")
v.Add("friend", "Sarah")
v.Add("friend", "Zoe")
// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"
fmt.Println(v.Get("name"))
fmt.Println(v.Get("friend"))
fmt.Println(v["friend"])

Request 자체 도 FormValue () 함 수 를 제공 하여 사용자 가 제출 한 인 자 를 가 져 옵 니 다.r. Form [username] 과 같이 r. FormValue (username) 로 도 쓸 수 있 습 니 다.r. FormValue 를 호출 할 때 r. ParseForm 을 자동 으로 호출 하기 때문에 미리 호출 할 필요 가 없습니다.r. FormValue 는 같은 이름 의 매개 변수 중 첫 번 째 만 되 돌려 주 고 매개 변수 가 존재 하지 않 으 면 빈 문자열 을 되 돌려 줍 니 다.
서버 폼 검증
이 부분 은 검증 숫자, 중국어, 이름, 번호 등 검증 해 야 할 많은 것 을 말 했 는데 주로 정규 검증 을 통 해 논리 구조 검증 을 통 해 관련 가방 을 호출 하 는 것 이다.
크로스 오 버 스 크 립 트 예방
현재 의 사 이 트 는 사용자 체험 을 향상 시 키 기 위해 대량의 동적 내용 을 포함 하고 있어 과거 보다 훨씬 복잡 하 다.동적 내용 이란 사용자 환경 과 수요 에 따라 웹 프로그램 이 해당 하 는 내용 을 출력 할 수 있 는 것 이다.동적 사 이 트 는 '크로스 사이트 스 크 립 트 공격' (Cross Site Scripting, 보안 전문가 들 은 보통 XSS 로 약칭) 이라는 위협 을 받 지만 정적 사 이 트 는 전혀 영향 을 받 지 않 습 니 다.
공격 자 는 보통 구멍 이 있 는 프로그램 에 자 바스 크 립 트, VBScript, ActiveX 또는 Flash 를 삽입 하여 사용 자 를 속인다.일단 손 에 넣 으 면 사용자 계 정 정 정 보 를 훔 치고 사용자 설정 을 수정 하 며 쿠키 를 훔 치 거나 오염 시 키 거나 악성 광 고 를 삽입 할 수 있다.
XSS 에 대한 가장 좋 은 방 호 는 다음 과 같은 두 가지 방법 을 결합 해 야 한다. 하 나 는 모든 입력 데 이 터 를 검증 하고 공격 을 효과적으로 검 측 하 는 것 이다 (이것 은 우리 앞의 소절 이 이미 소개 되 었 다).다른 하 나 는 성공 적 으로 주 입 된 스 크 립 트 가 브 라 우 저 에서 실행 되 지 않도록 모든 출력 데 이 터 를 적 절 히 처리 하 는 것 입 니 다.
주로 전 의 를 통 해 이 를 실현 하고 text / template 와 html / template 를 사용 합 니 다.
양식 을 여러 번 제출 하 는 것 을 방지 하 다.
한 포럼 이나 블 로 그 를 본 적 이 있 는 지 모 르 겠 지만, 한 댓 글 이나 글 뒤에 여러 개의 중복 기록 이 있 는 것 은 대부분 사용자 가 댓 글 의 양식 을 반복 해서 제출 했 기 때문이다.여러 가지 원인 으로 인해 사용 자 는 자주 양식 을 반복 해서 건네준다.일반적으로 이것 은 마우스 의 오 작 동 일 뿐 입 니 다. 예 를 들 어 배달 단 추 를 두 번 눌 렀 을 때 작성 한 정 보 를 편집 하거나 다시 확인 하기 위해 브 라 우 저의 후퇴 단 추 를 눌 렀 을 수도 있 습 니 다. 그리고 브 라 우 저의 전진 단추 가 아 닌 배달 단 추 를 다시 눌 렀 을 수도 있 습 니 다.물론 고의 일 수도 있다. 예 를 들 어 어떤 온라인 조사 나 로 또 행사 에서 중복 투 표를 하 는 것 이다.그러면 우 리 는 어떻게 사용자 가 같은 양식 을 여러 번 제출 하 는 것 을 효과적으로 방지 합 니까?
해결 방안 은 폼 에 유일한 값 을 가 진 숨겨 진 필드 를 추가 하 는 것 입 니 다.폼 을 검증 할 때, 이 유일한 값 을 가 진 폼 이 이미 제출 되 었 는 지 확인 하 십시오.만약 그렇다면, 다시 제출 하 는 것 을 거절 합 니 다.그렇지 않 으 면, 폼 을 처리 하여 논리 적 으로 처리한다.또한, Ajax 모드 로 양식 을 제출 한 경우, 양식 을 제출 한 후 자바 script 을 통 해 폼 의 제출 단 추 를 사용 하지 않 습 니 다.

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method) //       
    if r.Method == "GET" {
        crutime := time.Now().Unix()
        h := md5.New()
        io.WriteString(h, strconv.FormatInt(crutime, 10))
        token := fmt.Sprintf("%x", h.Sum(nil))

        t, _ := template.ParseFiles("login.gtpl")
        t.Execute(w, token)
    } else {
        //        ,           
        r.ParseForm()
        token := r.Form.Get("token")
        if token != "" {
            //  token    
        } else {
            //   token  
        }
        fmt.Println("username length:", len(r.Form["username"][0]))
        fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) //       
        fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password")))
        template.HTMLEscape(w, []byte(r.Form.Get("username"))) //      
    }
}

유일 성 을 이용 해 판단 하지만 악의 적 인 공격 을 막 을 수 는 없다.
파일 업로드 처리
사용자 가 올 린 파일 을 처리 하고 싶 습 니 다. 예 를 들 어 인 스타 그램 과 유사 한 사 이 트 를 만 들 고 있 습 니 다. 사용자 가 찍 은 사진 을 저장 해 야 합 니 다.이런 수 요 는 어떻게 실현 해 야 합 니까?
폼 이 파일 을 업로드 할 수 있 도록 하려 면 먼저 form 의 enctype 속성 을 추가 하 는 것 입 니 다. enctype 속성 은 다음 과 같은 세 가지 상황 이 있 습 니 다.
  • application / x - www - form - urlencoded 는 보 내기 전에 모든 문 자 를 인 코딩 하 는 것 을 표시 합 니 다 (기본 값)
  • multipart / form - data 는 문자 인 코딩 이 아 닙 니 다.파일 업로드 컨트롤 을 포함 하 는 폼 을 사용 할 때 이 값 을 사용 해 야 합 니 다.
  • text / plain 빈 칸 은 '+' 플러스 로 바 뀌 었 으 나 특수 문자 인 코딩 이 아 닙 니 다.

  • 파일 업로드 주요 3 단계 처리:
         enctype="multipart/form-data"
         r.ParseMultipartForm,                 
      r.FormFile      ,            

    Go 는 아 날로 그 클 라 이언 트 폼 기능 지원 파일 업 로드 를 지원 합 니 다. 자세 한 용법 은 다음 예제 를 보십시오.
    package main
    
    import (
        "bytes"
        "fmt"
        "io"
        "io/ioutil"
        "mime/multipart"
        "net/http"
        "os"
    )
    
    func postFile(filename string, targetUrl string) error {
        bodyBuf := &bytes.Buffer{}
        bodyWriter := multipart.NewWriter(bodyBuf)
    
        //       
        fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename)
        if err != nil {
            fmt.Println("error writing to buffer")
            return err
        }
    
        //        
        fh, err := os.Open(filename)
        if err != nil {
            fmt.Println("error opening file")
            return err
        }
        defer fh.Close()
        
        //iocopy
        _, err = io.Copy(fileWriter, fh)
        if err != nil {
            return err
        }
    
        contentType := bodyWriter.FormDataContentType()
        bodyWriter.Close()
    
        resp, err := http.Post(targetUrl, contentType, bodyBuf)
        if err != nil {
            return err
        }
        defer resp.Body.Close()
        resp_body, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            return err
        }
        fmt.Println(resp.Status)
        fmt.Println(string(resp_body))
        return nil
    }
    
    // sample usage
    func main() {
        target_url := "http://localhost:9090/upload"
        filename := "./astaxie.pdf"
        postFile(filename, target_url)
    }

    이 장 에서 저 희 는 Go 가 폼 정 보 를 어떻게 처리 하 는 지 배 웠 습 니 다. 저 희 는 사용자 로그 인, 파일 업로드 의 예 를 통 해 Go 가 form 폼 정 보 를 처리 하고 파일 을 업로드 하 는 수단 을 보 여 주 었 습 니 다.그러나 폼 을 처리 하 는 과정 에서 저 희 는 사용자 가 입력 한 정 보 를 검증 해 야 합 니 다. 사이트 안전 의 중요성 을 고려 하여 데이터 여과 이 상당히 중요 합 니 다. 그래서 뒤의 장 에 서로 다른 데이터 여과 을 설명 하 는 소절 을 전문 적 으로 썼 습 니 다. 그리고 Go 가 문자열 에 대한 정규 처 리 를 말씀 드 리 겠 습 니 다.
    클 라 이언 트 와 서버 측 이 어떻게 데이터 상의 상호작용 을 하 는 지 클 라 이언 트 는 데 이 터 를 서버 시스템 에 전달 하고 서버 는 데 이 터 를 받 아들 이 며 처리 결 과 를 클 라 이언 트 에 게 피드백 합 니 다.
    링크

    좋은 웹페이지 즐겨찾기