authorize validates the JWT that may be provided through an "Authorization" HTTP header or an authorization cookie. It returns the claims contained in the token if it exists and is valid, nil if no token is provided (anonymous mode), and an error if the token is not valid.
(r *http.Request, publish bool)
| 69 | // authorize validates the JWT that may be provided through an "Authorization" HTTP header or an authorization cookie. |
| 70 | // It returns the claims contained in the token if it exists and is valid, nil if no token is provided (anonymous mode), and an error if the token is not valid. |
| 71 | func (h *Hub) authorize(r *http.Request, publish bool) (*claims, error) { //nolint:funlen |
| 72 | var jwtKeyfunc jwt.Keyfunc |
| 73 | if publish { |
| 74 | jwtKeyfunc = h.publisherJWTKeyFunc |
| 75 | } else { |
| 76 | jwtKeyfunc = h.subscriberJWTKeyFunc |
| 77 | } |
| 78 | |
| 79 | authorizationHeaders, authorizationHeaderExists := r.Header["Authorization"] |
| 80 | if authorizationHeaderExists { |
| 81 | if len(authorizationHeaders) != 1 || len(authorizationHeaders[0]) < 48 || authorizationHeaders[0][:7] != bearerPrefix { |
| 82 | return nil, ErrInvalidAuthorizationHeader |
| 83 | } |
| 84 | |
| 85 | return validateJWT(authorizationHeaders[0][7:], jwtKeyfunc) |
| 86 | } |
| 87 | |
| 88 | if authorizationQuery, queryExists := r.URL.Query()["authorization"]; queryExists { |
| 89 | if len(authorizationQuery) != 1 || len(authorizationQuery[0]) < 41 { |
| 90 | return nil, ErrInvalidAuthorizationQuery |
| 91 | } |
| 92 | |
| 93 | return validateJWT(authorizationQuery[0], jwtKeyfunc) |
| 94 | } |
| 95 | |
| 96 | cookie, err := r.Cookie(h.cookieName) |
| 97 | if err != nil { |
| 98 | // Anonymous |
| 99 | return nil, nil //nolint:nilerr,nilnil |
| 100 | } |
| 101 | |
| 102 | // CSRF attacks cannot occur when using safe methods |
| 103 | if r.Method != http.MethodPost { |
| 104 | return validateJWT(cookie.Value, jwtKeyfunc) |
| 105 | } |
| 106 | |
| 107 | origin := r.Header.Get("Origin") |
| 108 | if origin == "" { |
| 109 | // Try to extract the origin from the Referer, or return an error |
| 110 | referer := r.Header.Get("Referer") |
| 111 | if referer == "" { |
| 112 | return nil, ErrNoOrigin |
| 113 | } |
| 114 | |
| 115 | u, err := url.Parse(referer) |
| 116 | if err != nil { |
| 117 | return nil, fmt.Errorf("unable to parse referer: %w", err) |
| 118 | } |
| 119 | |
| 120 | origin = fmt.Sprintf("%s://%s", u.Scheme, u.Host) |
| 121 | } |
| 122 | |
| 123 | if h.publishOriginsAll { |
| 124 | return validateJWT(cookie.Value, jwtKeyfunc) |
| 125 | } |
| 126 | |
| 127 | if slices.Contains(h.publishOrigins, origin) { |
| 128 | return validateJWT(cookie.Value, jwtKeyfunc) |