gitea源码

cookie.go 2.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2020 The Macaron Authors
  2. // Copyright 2020 The Gitea Authors. All rights reserved.
  3. // SPDX-License-Identifier: MIT
  4. package middleware
  5. import (
  6. "net/http"
  7. "net/url"
  8. "strings"
  9. "code.gitea.io/gitea/modules/session"
  10. "code.gitea.io/gitea/modules/setting"
  11. )
  12. // SetRedirectToCookie convenience function to set the RedirectTo cookie consistently
  13. func SetRedirectToCookie(resp http.ResponseWriter, value string) {
  14. SetSiteCookie(resp, "redirect_to", value, 0)
  15. }
  16. // DeleteRedirectToCookie convenience function to delete most cookies consistently
  17. func DeleteRedirectToCookie(resp http.ResponseWriter) {
  18. SetSiteCookie(resp, "redirect_to", "", -1)
  19. }
  20. // GetSiteCookie returns given cookie value from request header.
  21. func GetSiteCookie(req *http.Request, name string) string {
  22. cookie, err := req.Cookie(name)
  23. if err != nil {
  24. return ""
  25. }
  26. val, _ := url.QueryUnescape(cookie.Value)
  27. return val
  28. }
  29. // SetSiteCookie returns given cookie value from request header.
  30. func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) {
  31. // Previous versions would use a cookie path with a trailing /.
  32. // These are more specific than cookies without a trailing /, so
  33. // we need to delete these if they exist.
  34. deleteLegacySiteCookie(resp, name)
  35. cookie := &http.Cookie{
  36. Name: name,
  37. Value: url.QueryEscape(value),
  38. MaxAge: maxAge,
  39. Path: setting.SessionConfig.CookiePath,
  40. Domain: setting.SessionConfig.Domain,
  41. Secure: setting.SessionConfig.Secure,
  42. HttpOnly: true,
  43. SameSite: setting.SessionConfig.SameSite,
  44. }
  45. resp.Header().Add("Set-Cookie", cookie.String())
  46. }
  47. // deleteLegacySiteCookie deletes the cookie with the given name at the cookie
  48. // path with a trailing /, which would unintentionally override the cookie.
  49. func deleteLegacySiteCookie(resp http.ResponseWriter, name string) {
  50. if setting.SessionConfig.CookiePath == "" || strings.HasSuffix(setting.SessionConfig.CookiePath, "/") {
  51. // If the cookie path ends with /, no legacy cookies will take
  52. // precedence, so do nothing. The exception is that cookies with no
  53. // path could override other cookies, but it's complicated and we don't
  54. // currently handle that.
  55. return
  56. }
  57. cookie := &http.Cookie{
  58. Name: name,
  59. Value: "",
  60. MaxAge: -1,
  61. Path: setting.SessionConfig.CookiePath + "/",
  62. Domain: setting.SessionConfig.Domain,
  63. Secure: setting.SessionConfig.Secure,
  64. HttpOnly: true,
  65. SameSite: setting.SessionConfig.SameSite,
  66. }
  67. resp.Header().Add("Set-Cookie", cookie.String())
  68. }
  69. func init() {
  70. session.BeforeRegenerateSession = append(session.BeforeRegenerateSession, func(resp http.ResponseWriter, _ *http.Request) {
  71. // Ensure that a cookie with a trailing slash does not take precedence over
  72. // the cookie written by the middleware.
  73. deleteLegacySiteCookie(resp, setting.SessionConfig.CookieName)
  74. })
  75. }