コード例 #1
1
ファイル: cookies.go プロジェクト: extrame/goweb
// AddSignedCookie adds the specified cookie to the response and also adds an
// additional 'signed' cookie that is used to validate the cookies value when
// SignedCookie is called.
func (c *Context) AddSignedCookie(cookie *http.Cookie) (*http.Cookie, error) {

	// make the signed cookie
	signedCookie := new(http.Cookie)

	// copy the cookie settings
	signedCookie.Path = cookie.Path
	signedCookie.Domain = cookie.Domain
	signedCookie.RawExpires = cookie.RawExpires
	signedCookie.Expires = cookie.Expires
	signedCookie.MaxAge = cookie.MaxAge
	signedCookie.Secure = cookie.Secure
	signedCookie.HttpOnly = cookie.HttpOnly
	signedCookie.Raw = cookie.Raw

	// set the signed cookie specifics
	signedCookie.Name = toSignedCookieName(cookie.Name)
	signedCookie.Value = Hash(cookie.Value)

	// add the cookies
	http.SetCookie(c.ResponseWriter, cookie)
	http.SetCookie(c.ResponseWriter, signedCookie)

	// return the new signed cookie (and no error)
	return signedCookie, nil

}
コード例 #2
1
ファイル: okalib.go プロジェクト: nus/escape3ds_angularjs
/**
 * クッキーを作成する
 * @function
 * @param {string} name クッキーの名前
 * @param {string} value クッキーの値
 * @param {string} domain 有効ドメイン
 * @param {string} path 有効ディレクトリ
 * @param {int} hour 有効期限(時間)
 */
func NewCookie(name string, value string, domain string, path string, hour int) *http.Cookie {
	duration := time.Hour * time.Duration(hour)
	now := time.Now()
	expire := now.Add(duration)

	cookie := new(http.Cookie)
	cookie.Name = name
	cookie.Value = value
	cookie.Domain = domain
	cookie.Path = path
	cookie.Expires = expire
	cookie.RawExpires = expire.Format(time.UnixDate)
	cookie.MaxAge = 60 * 60 * hour
	cookie.Secure = false
	cookie.HttpOnly = true
	cookie.Raw = fmt.Sprintf("%s=%s", cookie.Name, cookie.Value)
	cookie.Unparsed = []string{cookie.Raw}

	return cookie
}
コード例 #3
0
ファイル: oauth1.go プロジェクト: bibinbin/go.auth
// Redirects the User to the OAuth1.0a provider's Login Screen. A RequestToken
// is requested from the Provider, and included in the URL's oauth_token param.
//
// A Successful Login / Authorization should return both the oauth_token and
// the oauth_verifier to the callback URL.
func (self *OAuth1Mixin) AuthorizeRedirect(w http.ResponseWriter, r *http.Request, endpoint string) error {

	//Get a Request Token
	token, err := self.Consumer.RequestToken()
	if err != nil {
		return err
	}

	//Get the redirect URL
	url, err := self.Consumer.AuthorizeRedirect(token)
	if err != nil {
		return err
	}

	//Write the Request Token to a Cookie, so that we can
	//retrieve it after re-directing the user to the
	//providers authorization screen.
	cookie := http.Cookie{}
	cookie.Name = "_token"
	cookie.Path = "/"
	cookie.Domain = r.URL.Host
	cookie.HttpOnly = true
	cookie.Secure = Config.CookieSecure
	cookie.Value = token.Encode()
	http.SetCookie(w, &cookie)

	// redirect to the login url
	http.Redirect(w, r, url, http.StatusSeeOther)
	return nil
}
コード例 #4
0
// Answers to /sso, returns the SSO cookie and redirects to /startpage
func handler(w http.ResponseWriter, r *http.Request) {
	re := regexp.MustCompile("CN=([ 0-9A-Za-z_]+)")

	user := r.Header.Get("Certificate-User")
	if user == "" {
		log.Panicf("Did not get user!")
	}

	match := re.FindStringSubmatch(user)

	if len(match) != 2 {
		log.Panicf("No CN found!")
	}

	cn := match[1]

	sessionid := getSessionID(cn, r.Header.Get("X-Forwarded-For"))
	token := generate_session_token(sessionid, cn)
	signature := sign_session_token(token)

	cookie := http.Cookie{}
	cookie.Name = "PLAY_SESSION"
	cookie.Value = signature + "-" + token
	cookie.Path = "/"
	cookie.Domain = external_host
	cookie.Expires = time.Now().Add(356 * 24 * time.Hour)
	cookie.HttpOnly = true
	http.SetCookie(w, &cookie)

	http.Redirect(w, r, "/startpage", http.StatusFound)
}
コード例 #5
0
ファイル: monim.go プロジェクト: LDCS/monim
func createCookie(key, val string) *http.Cookie {
	cookie := new(http.Cookie)
	cookie.Name = key
	cookie.Value = val
	cookie.HttpOnly = false
	cookie.Path = "/" // Without this ang js cant read cookies we send
	//cookie.Expires = expire
	return cookie
}
コード例 #6
0
func (s *FormsAuthSuite) createCookie(token string) http.Cookie {
	cookie := http.Cookie{}
	cookie.Name = FormsAuthenticatorDefaultCookieName
	cookie.Expires = time.Now().UTC().Add(24 * 365 * time.Hour)
	cookie.HttpOnly = true
	cookie.Path = "/"
	cookie.Value = token
	return cookie
}
コード例 #7
0
ファイル: plug-info.go プロジェクト: ThomasRooney/grunk
func constructCookie(name string, value string) *http.Cookie {
	cookie := new(http.Cookie)
	cookie.Name = name
	cookie.Value = value
	cookie.Path = "/"
	cookie.HttpOnly = false
	cookie.Secure = false
	return cookie
}
コード例 #8
0
ファイル: forms_auth.go プロジェクト: activegiver/logingo
func (auth *FormsAuthenticator) createAuthCookie(jwtString string) *http.Cookie {
	cookie := http.Cookie{}
	cookie.Name = auth.CookieName
	cookie.Expires = auth.getCookieExpirationTime()
	cookie.HttpOnly = true
	cookie.Path = "/"
	cookie.Value = jwtString
	return &cookie
}
コード例 #9
0
ファイル: spacecookies.go プロジェクト: jhautefeuille/misc
// parse parses a Set-Cookie header into a cookie.
// It supports space in name unlike net/http.
// Returns nil if invalid.
func parse(s string) *http.Cookie {
	var c http.Cookie
	for i, field := range strings.Split(s, ";") {
		if len(field) == 0 {
			continue
		}
		nv := strings.SplitN(field, "=", 2)
		name := strings.TrimSpace(nv[0])
		value := ""
		if len(nv) > 1 {
			value = strings.TrimSpace(nv[1])
		}
		if i == 0 {
			if len(nv) != 2 {
				continue
			}
			c.Name = name
			c.Value = value
			continue
		}
		switch strings.ToLower(name) {
		case "secure":
			c.Secure = true
		case "httponly":
			c.HttpOnly = true
		case "domain":
			c.Domain = value
		case "max-age":
			secs, err := strconv.Atoi(value)
			if err != nil || secs != 0 && value[0] == '0' {
				continue
			}
			if secs <= 0 {
				c.MaxAge = -1
			} else {
				c.MaxAge = secs
			}
		case "expires":
			exptime, err := time.Parse(time.RFC1123, value)
			if err != nil {
				exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", value)
				if err != nil {
					c.Expires = time.Time{}
					continue
				}
			}
			c.Expires = exptime.UTC()
		case "path":
			c.Path = value
		}
	}
	if c.Name == "" {
		return nil
	}
	return &c
}
コード例 #10
0
ファイル: cookie.go プロジェクト: juztin/wombat
func cookie(val string) *http.Cookie {
	c := new(http.Cookie)
	c.Name = config.Cookie
	c.Value = val
	c.Domain = config.ServerDomain
	c.Path = config.CookiePath
	c.HttpOnly = config.CookieHttpOnly
	c.Secure = config.CookieSecure
	return c
}
コード例 #11
0
ファイル: monim.go プロジェクト: LDCS/monim
func createBlankCookie(key string) *http.Cookie {
	cookie := new(http.Cookie)
	cookie.Name = key
	cookie.Value = ""
	l, _ := time.LoadLocation("UTC")
	cookie.Expires = time.Date(1970, time.January, 1, 0, 0, 0, 0, l)
	cookie.HttpOnly = false
	cookie.Path = "/" // Without this ang js cant read cookies we send
	return cookie
}
コード例 #12
0
ファイル: ctx.go プロジェクト: elago/ela
// set cookie
// args: name, value, max age, path, domain, secure, http only, expires
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
	cookie := http.Cookie{}
	cookie.Name = name
	cookie.Value = url.QueryEscape(value)

	if len(others) > 0 {
		switch v := others[0].(type) {
		case int:
			cookie.MaxAge = v
		case int64:
			cookie.MaxAge = int(v)
		case int32:
			cookie.MaxAge = int(v)
		}
	}

	cookie.Path = "/"
	if len(others) > 1 {
		if v, ok := others[1].(string); ok && len(v) > 0 {
			cookie.Path = v
		}
	}

	if len(others) > 2 {
		if v, ok := others[2].(string); ok && len(v) > 0 {
			cookie.Domain = v
		}
	}

	if len(others) > 3 {
		switch v := others[3].(type) {
		case bool:
			cookie.Secure = v
		default:
			if others[3] != nil {
				cookie.Secure = true
			}
		}
	}

	if len(others) > 4 {
		if v, ok := others[4].(bool); ok && v {
			cookie.HttpOnly = true
		}
	}

	if len(others) > 5 {
		if v, ok := others[5].(time.Time); ok {
			cookie.Expires = v
			cookie.RawExpires = v.Format(time.UnixDate)
		}
	}

	ctx.w.Header().Add("Set-Cookie", cookie.String())
}
コード例 #13
0
ファイル: sessions.go プロジェクト: kobeld/mango
func commitSession(headers Headers, env Env, key, secret string, options *CookieOptions) {
	cookie := new(http.Cookie)
	cookie.Name = key
	cookie.Value = encodeCookie(env["mango.session"].(map[string]interface{}), secret)
	cookie.Path = options.Path
	cookie.Domain = options.Domain
	cookie.MaxAge = options.MaxAge
	cookie.Secure = options.Secure
	cookie.HttpOnly = options.HttpOnly
	headers.Add("Set-Cookie", cookie.String())
}
コード例 #14
0
ファイル: sessions.go プロジェクト: dangchienhsgs/mango
func commitSession(headers Headers, env Env, key, secret string, newValue string, options *CookieOptions) {
	cookie := new(http.Cookie)
	cookie.Name = key
	cookie.Value = newValue
	cookie.Path = options.Path
	cookie.Domain = options.Domain
	cookie.MaxAge = options.MaxAge
	cookie.Secure = options.Secure
	cookie.HttpOnly = options.HttpOnly
	headers.Add("Set-Cookie", cookie.String())
}
コード例 #15
0
ファイル: context.go プロジェクト: numo16/gogs
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
	cookie := http.Cookie{}
	cookie.Name = name
	cookie.Value = value

	if len(others) > 0 {
		switch v := others[0].(type) {
		case int:
			cookie.MaxAge = v
		case int64:
			cookie.MaxAge = int(v)
		case int32:
			cookie.MaxAge = int(v)
		}
	}

	// default "/"
	if len(others) > 1 {
		if v, ok := others[1].(string); ok && len(v) > 0 {
			cookie.Path = v
		}
	} else {
		cookie.Path = "/"
	}

	// default empty
	if len(others) > 2 {
		if v, ok := others[2].(string); ok && len(v) > 0 {
			cookie.Domain = v
		}
	}

	// default empty
	if len(others) > 3 {
		switch v := others[3].(type) {
		case bool:
			cookie.Secure = v
		default:
			if others[3] != nil {
				cookie.Secure = true
			}
		}
	}

	// default false. for session cookie default true
	if len(others) > 4 {
		if v, ok := others[4].(bool); ok && v {
			cookie.HttpOnly = true
		}
	}

	ctx.Res.Header().Add("Set-Cookie", cookie.String())
}
コード例 #16
0
ファイル: processor.go プロジェクト: kdada/tinygo
// createCookie 创建cookie
func (this *HttpProcessor) createCookie(name string, id string, expire int) *http.Cookie {
	var cookieValue = new(http.Cookie)
	cookieValue.Name = name
	cookieValue.Value = id
	cookieValue.Path = "/"
	cookieValue.HttpOnly = true
	if expire > 0 {
		cookieValue.MaxAge = expire
		cookieValue.Expires = time.Now().Add(time.Second * time.Duration(expire))
	}
	return cookieValue
}
コード例 #17
0
ファイル: seshcookie.go プロジェクト: beatgammit/seshcookie
func (s sessionResponseWriter) WriteHeader(code int) {
	if atomic.AddInt32(&s.wroteHeader, 1) == 1 {
		origCookie, err := s.req.Cookie(s.h.CookieName)
		var origCookieVal string
		if err != nil {
			origCookieVal = ""
		} else {
			origCookieVal = origCookie.Value
		}

		session := s.h.RS.Get(s.req)
		if len(session) == 0 {
			// if we have an empty session, but the
			// request didn't start out that way, we
			// assume the user wants us to clear the
			// session
			if origCookieVal != "" {
				//log.Println("clearing cookie")
				var cookie http.Cookie
				cookie.Name = s.h.CookieName
				cookie.Value = ""
				cookie.Path = "/"
				// a cookie is expired by setting it
				// with an expiration time in the past
				cookie.Expires = time.Unix(0, 0).UTC()
				http.SetCookie(s, &cookie)
			}
			goto write
		}
		encoded, gobHash, err := encodeCookie(session, s.h.encKey, s.h.hmacKey)
		if err != nil {
			log.Printf("createCookie: %s\n", err)
			goto write
		}

		if bytes.Equal(gobHash, s.h.RS.getHash(s.req)) {
			//log.Println("not re-setting identical cookie")
			goto write
		}

		var cookie http.Cookie
		cookie.Name = s.h.CookieName
		cookie.Value = encoded
		cookie.Path = s.h.CookiePath
		cookie.HttpOnly = s.h.RS.HttpOnly
		cookie.Secure = s.h.RS.Secure
		http.SetCookie(s, &cookie)
	}
write:
	s.ResponseWriter.WriteHeader(code)
}
コード例 #18
0
ファイル: utils.go プロジェクト: caizengjun/qor
// SetCookie set cookie for context
func SetCookie(cookie http.Cookie, context *qor.Context) {
	cookie.HttpOnly = true

	// set https cookie
	if context.Request != nil && context.Request.URL.Scheme == "https" {
		cookie.Secure = true
	}

	// set default path
	if cookie.Path == "" {
		cookie.Path = "/"
	}

	http.SetCookie(context.Writer, &cookie)
}
コード例 #19
0
ファイル: Reponse.go プロジェクト: kolonse/KolonseWeb
func (res *Response) SetCookie(name string, value string, others ...interface{}) {
	cookie := http.Cookie{}
	cookie.Name = name
	cookie.Value = url.QueryEscape(value)

	if len(others) > 0 {
		switch v := others[0].(type) {
		case int:
			cookie.MaxAge = v
		case int64:
			cookie.MaxAge = int(v)
		case int32:
			cookie.MaxAge = int(v)
		}
	}

	cookie.Path = "/"
	if len(others) > 1 {
		if v, ok := others[1].(string); ok && len(v) > 0 {
			cookie.Path = v
		}
	}

	if len(others) > 2 {
		if v, ok := others[2].(string); ok && len(v) > 0 {
			cookie.Domain = v
		}
	}

	if len(others) > 3 {
		switch v := others[3].(type) {
		case bool:
			cookie.Secure = v
		default:
			if others[3] != nil {
				cookie.Secure = true
			}
		}
	}

	if len(others) > 4 {
		if v, ok := others[4].(bool); ok && v {
			cookie.HttpOnly = true
		}
	}

	res.Header().Add("Set-Cookie", cookie.String())
}
コード例 #20
0
ファイル: main.go プロジェクト: orian/go-gin-bootstrap
func ProvideSession(c *gin.Context) {
	// decodes a session id from cookie or provides a new one
	if ck, err := c.Request.Cookie("session"); err == nil {
		c.Set("session", ck.Value)
		return
	}
	newSession := "alfa romeo"
	c.Set("session", newSession)
	// c.Writer.C
	cookie := http.Cookie{}
	cookie.Name = "session"
	cookie.Value = newSession
	cookie.Path = "/"
	cookie.Expires = time.Now().Add(time.Hour * 24 * 7)
	cookie.HttpOnly = true
	http.SetCookie(c.Writer, &cookie)
}
コード例 #21
0
ファイル: cookiestate.go プロジェクト: felipeweb/httpapp
func (state *SessionCookieState) createCookie(session *Session) *http.Cookie {
	cookie := http.Cookie{}
	cookie.Name = state.SessionKey
	cookie.Value = session.Id
	cookie.Path = state.Path
	cookie.Domain = state.Domain
	cookie.Secure = state.Secure
	cookie.HttpOnly = state.HttpOnly

	if session.IsExpired() {
		cookie.Expires = time.Now()
	} else {
		if state.Expires != 0 {
			cookie.Expires = time.Now().Add(state.Expires)
		}
	}

	return &cookie
}
コード例 #22
0
ファイル: handler.go プロジェクト: Monory/messenger
func defaultHandler(w http.ResponseWriter, r *http.Request, db *sql.DB) {
	cookieToken, err := r.Cookie("token")
	if err != nil {
		if err == http.ErrNoCookie {
			http.Redirect(w, r, "/auth", http.StatusSeeOther)
			return
		}
		internalServerError(w, err)
		return
	}

	token := auth.NewUserToken()
	err = token.FromString(cookieToken.Value)
	if err == nil {
		err = auth.CheckUserToken(db, token)
	}
	if err != nil {
		if _, ok := err.(auth.AuthError); ok {
			var c http.Cookie
			c.Name = "token"
			c.MaxAge = -1
			c.Secure = true
			c.HttpOnly = true

			http.SetCookie(w, &c)
			http.Redirect(w, r, "/", http.StatusSeeOther)
			return
		}
		internalServerError(w, err)
		return
	}

	if r.URL.Path != "/" {
		http.Redirect(w, r, "/", http.StatusSeeOther)
		return
	}

	chatHandler(w, r, db)
}
コード例 #23
0
ファイル: cookies_test.go プロジェクト: extrame/goweb
func TestAddSignedCookie(t *testing.T) {

	context := MakeTestContext()
	cookie := new(http.Cookie)
	cookie.Name = "userId"
	cookie.Value = "2468"
	cookie.Path = "/something"
	cookie.Domain = "domain"
	cookie.RawExpires = "NOW"
	cookie.Expires = time.Now()
	cookie.MaxAge = 123
	cookie.Secure = true
	cookie.HttpOnly = true
	cookie.Raw = "userId=2468;"

	signedCookie, err := context.AddSignedCookie(cookie)

	if err != nil {
		t.Errorf("AddSignedCookie shouldn't return an error: %s", err)
		return
	}

	assertEqual(t, signedCookie.Name, fmt.Sprintf("%s_signed", cookie.Name), "Cookie name")
	assertEqual(t, signedCookie.Value, Hash(cookie.Value), "Cookie value (signed)")

	// assert the rest of the values were also copied
	assertEqual(t, signedCookie.Path, cookie.Path, "Path")
	assertEqual(t, signedCookie.Domain, cookie.Domain, "Domain")
	assertEqual(t, signedCookie.RawExpires, cookie.RawExpires, "RawExpires")
	assertEqual(t, signedCookie.Expires, cookie.Expires, "Expires")
	assertEqual(t, signedCookie.MaxAge, cookie.MaxAge, "MaxAge")
	assertEqual(t, signedCookie.Secure, cookie.Secure, "Secure")
	assertEqual(t, signedCookie.HttpOnly, cookie.HttpOnly, "HttpOnly")
	assertEqual(t, signedCookie.Raw, cookie.Raw, "Raw")

}
コード例 #24
0
ファイル: users.go プロジェクト: nicolai86/dash-annotations
// UserLogin tries to authenticate an existing user using username/ password combination
func UserLogin(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
	var payload userLoginRequest
	json.NewDecoder(req.Body).Decode(&payload)

	if payload.Username == "" {
		return ErrMissingUsername
	}
	if payload.Password == "" {
		return ErrMissingPassword
	}

	var loginStore = ctx.Value(UserStoreKey).(userLoginStore)
	var user, err = loginStore.FindUserByUsername(payload.Username)
	if err != nil {
		return ErrInvalidLogin
	}

	if !user.PasswordsMatch(payload.Password) {
		return ErrInvalidLogin
	}

	var sessionID, _ = generateRandomString(32)

	if err := loginStore.UpdateUserWithToken(user.Username, sessionID); err != nil {
		return err
	}

	var ckie *http.Cookie
	for _, cookie := range req.Cookies() {
		if cookie.Name == "laravel_session" {
			ckie = cookie
			break
		}
	}

	if ckie == nil {
		ckie = &http.Cookie{
			Name: "laravel_session",
		}
	}

	if encryptedSessionID, err := encrypt([]byte(sessionID)); err != nil {
		return err
	} else {
		ckie.Value = string(encryptedSessionID)
	}
	ckie.MaxAge = 7200
	ckie.Expires = time.Now().Add(7200 * time.Second)
	ckie.Path = "/"
	ckie.HttpOnly = true
	http.SetCookie(w, ckie)

	w.WriteHeader(http.StatusOK)
	var data = map[string]string{
		"status": "success",
	}
	if user.Email.String != "" {
		data["email"] = user.Email.String
	}
	json.NewEncoder(w).Encode(data)
	return nil
}
コード例 #25
0
ファイル: minsession.go プロジェクト: stuphlabs/pullcord
func (handler *MinSessionHandler) genCookie() (*http.Cookie, error) {
	log().Debug("minsession generating cookie")

	handler.assureTableInitialized()

	var randReadErr error
	var otherErr error

	nbytes := make([]byte, minSessionCookieNameRandSize)
	vbytes := make([]byte, minSessionCookieValueRandSize)

	cookie_name := ""
	name_gen_needed := true
	for name_gen_needed {
		_, randReadErr = rand.Read(nbytes)
		if randReadErr != nil {
			log().Err(
				"minsession cookie generation was unable to" +
					" read the needed random bytes",
			)
			return nil, randReadErr
		}

		cookie_name = handler.Name + "-" + hex.EncodeToString(nbytes)
		// Slower than adding an else on the next if, but clearer.
		name_gen_needed = false

		_, collision := handler.table[cookie_name]
		if collision {
			// We had a collision with an existing legit cookie?
			// Is the random number generator broken?
			log().Err(
				fmt.Sprintf(
					"minsession cookie generation has"+
						" created a new cookie with a name"+
						" that collides with an already"+
						" existing cookie from the cookie"+
						" table which shares the name: %s",
					cookie_name,
				),
			)
			name_gen_needed = true
			otherErr = rngCollisionError
		}
	}

	_, randReadErr = rand.Read(vbytes)
	if randReadErr != nil {
		log().Err(
			"minsession cookie generation was unable to" +
				" read the needed random bytes",
		)
		return nil, randReadErr
	}

	var cke http.Cookie
	cke.Name = cookie_name
	// TODO delete
	log().Debug(fmt.Sprintf("got %v", handler))
	cke.Value = hex.EncodeToString(vbytes)
	cke.Path = handler.Path
	cke.Domain = handler.Domain
	cke.MaxAge = minSessionCookieMaxAge
	cke.Secure = true
	cke.HttpOnly = true

	return &cke, otherErr
}
コード例 #26
0
ファイル: csrf.go プロジェクト: luizbafilho/fusis
// CSRFWithConfig returns a CSRF middleware with config.
// See `CSRF()`.
func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc {
	// Defaults
	if config.Skipper == nil {
		config.Skipper = DefaultCSRFConfig.Skipper
	}
	if config.TokenLength == 0 {
		config.TokenLength = DefaultCSRFConfig.TokenLength
	}
	if config.TokenLookup == "" {
		config.TokenLookup = DefaultCSRFConfig.TokenLookup
	}
	if config.ContextKey == "" {
		config.ContextKey = DefaultCSRFConfig.ContextKey
	}
	if config.CookieName == "" {
		config.CookieName = DefaultCSRFConfig.CookieName
	}
	if config.CookieMaxAge == 0 {
		config.CookieMaxAge = DefaultCSRFConfig.CookieMaxAge
	}

	// Initialize
	parts := strings.Split(config.TokenLookup, ":")
	extractor := csrfTokenFromHeader(parts[1])
	switch parts[0] {
	case "form":
		extractor = csrfTokenFromForm(parts[1])
	case "query":
		extractor = csrfTokenFromQuery(parts[1])
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.Skipper(c) {
				return next(c)
			}

			req := c.Request()
			k, err := c.Cookie(config.CookieName)
			token := ""

			if err != nil {
				// Generate token
				token = random.String(config.TokenLength)
			} else {
				// Reuse token
				token = k.Value
			}

			switch req.Method {
			case echo.GET, echo.HEAD, echo.OPTIONS, echo.TRACE:
			default:
				// Validate token only for requests which are not defined as 'safe' by RFC7231
				clientToken, err := extractor(c)
				if err != nil {
					return err
				}
				if !validateCSRFToken(token, clientToken) {
					return echo.NewHTTPError(http.StatusForbidden, "csrf token is invalid")
				}
			}

			// Set CSRF cookie
			cookie := new(http.Cookie)
			cookie.Name = config.CookieName
			cookie.Value = token
			if config.CookiePath != "" {
				cookie.Path = config.CookiePath
			}
			if config.CookieDomain != "" {
				cookie.Domain = config.CookieDomain
			}
			cookie.Expires = time.Now().Add(time.Duration(config.CookieMaxAge) * time.Second)
			cookie.Secure = config.CookieSecure
			cookie.HttpOnly = config.CookieHTTPOnly
			c.SetCookie(cookie)

			// Store token in the context
			c.Set(config.ContextKey, token)

			// Protect clients from caching the response
			c.Response().Header().Add(echo.HeaderVary, echo.HeaderCookie)

			return next(c)
		}
	}
}
コード例 #27
0
ファイル: handler.go プロジェクト: Monory/messenger
func authHandler(w http.ResponseWriter, r *http.Request, db *sql.DB) {
	err := r.ParseForm()
	if err != nil {
		internalServerError(w, err)
		return
	}

	var username, password string

	if len(r.PostForm) != 0 {
		username = r.PostFormValue("username")
		if !validate.Username(username) {
			renderAuth(w, errors.New("Bad username"))
			return
		}
		username = sanitize.Username(username)

		password = r.PostFormValue("password")
		if !validate.Password(password) {
			renderAuth(w, errors.New("Bad password"))
			return
		}

		switch {
		case r.PostFormValue("loginbutton") != "":
			var token *auth.UserToken
			token, err = auth.Login(db, username, password)
			if err != nil {
				if _, ok := err.(auth.AuthError); ok {
					renderAuth(w, errors.New("Bad login"))
					return
				}
				internalServerError(w, err)
				return
			}

			var c http.Cookie
			c.Name = "token"
			c.Value = token.String()
			c.MaxAge = 86400 * 7 // a week
			c.Secure = true
			c.HttpOnly = true

			http.SetCookie(w, &c)
			http.Redirect(w, r, "/", http.StatusSeeOther)
			return
		case r.PostFormValue("registerbutton") != "":
			err = auth.Register(db, username, password)
			if err != nil {
				if _, ok := err.(auth.AuthError); ok {
					renderAuth(w, errors.New("Bad register"))
					return
				}
				internalServerError(w, err)
				return
			}
			http.Redirect(w, r, "/auth", http.StatusSeeOther)
			return
		}

		renderAuth(w, errors.New("Bad request"))
		return
	}

	renderAuth(w, nil)
}