Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 39 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,37 +357,37 @@ func helloHandler(c *gin.Context) {

The `GinJWTMiddleware` struct provides the following configuration options:

| Option | Type | Required | Default | Description |
|---|---|---|---|---|
| Realm | `string` | No | `"gin jwt"` | Realm name to display to the user. |
| SigningAlgorithm | `string` | No | `"HS256"` | Signing algorithm (HS256, HS384, HS512, RS256, RS384, RS512). |
| Key | `[]byte` | Yes | - | Secret key used for signing. |
| Timeout | `time.Duration` | No | `time.Hour` | Duration that a jwt token is valid. |
| MaxRefresh | `time.Duration` | No | `0` | Duration that a refresh token is valid. |
| Authenticator | `func(c *gin.Context) (any, error)` | Yes | - | Callback to authenticate the user. Returns user data. |
| Authorizer | `func(c *gin.Context, data any) bool` | No | `true` | Callback to authorize the authenticated user. |
| PayloadFunc | `func(data any) jwt.MapClaims` | No | - | Callback to add additional payload data to the token. |
| Unauthorized | `func(c *gin.Context, code int, message string)` | No | - | Callback for unauthorized requests. |
| LoginResponse | `func(c *gin.Context, token *core.Token)` | No | - | Callback for successful login response. |
| LogoutResponse | `func(c *gin.Context)` | No | - | Callback for successful logout response. |
| RefreshResponse | `func(c *gin.Context, token *core.Token)` | No | - | Callback for successful refresh response. |
| IdentityHandler | `func(*gin.Context) any` | No | - | Callback to retrieve identity from claims. |
| IdentityKey | `string` | No | `"identity"` | Key used to store identity in claims. |
| TokenLookup | `string` | No | `"header:Authorization"` | Source to extract token from (header, query, cookie). |
| TokenHeadName | `string` | No | `"Bearer"` | Header name prefix. |
| TimeFunc | `func() time.Time` | No | `time.Now` | Function to provide current time. |
| PrivKeyFile | `string` | No | - | Path to private key file (for RS algorithms). |
| PubKeyFile | `string` | No | - | Path to public key file (for RS algorithms). |
| SendCookie | `bool` | No | `false` | Whether to send token as a cookie. |
| CookieMaxAge | `time.Duration` | No | `Timeout` | Duration that the cookie is valid. |
| SecureCookie | `bool` | No | `false` | Whether to use secure cookies (HTTPS only). |
| CookieHTTPOnly | `bool` | No | `false` | Whether to use HTTPOnly cookies. |
| CookieDomain | `string` | No | - | Domain for the cookie. |
| CookieName | `string` | No | `"jwt"` | Name of the cookie. |
| CookieSameSite | `http.SameSite` | No | - | SameSite attribute for the cookie. |
| SendAuthorization | `bool` | No | `false` | Whether to return authorization header for every request. |
| DisabledAbort | `bool` | No | `false` | Disable abort() of context. |
| ParseOptions | `[]jwt.ParserOption` | No | - | Options for parsing the JWT. |
| Option | Type | Required | Default | Description |
| ----------------- | ------------------------------------------------ | -------- | ------------------------ | ------------------------------------------------------------- |
| Realm | `string` | No | `"gin jwt"` | Realm name to display to the user. |
| SigningAlgorithm | `string` | No | `"HS256"` | Signing algorithm (HS256, HS384, HS512, RS256, RS384, RS512). |
| Key | `[]byte` | Yes | - | Secret key used for signing. |
| Timeout | `time.Duration` | No | `time.Hour` | Duration that a jwt token is valid. |
| MaxRefresh | `time.Duration` | No | `0` | Duration that a refresh token is valid. |
| Authenticator | `func(c *gin.Context) (any, error)` | Yes | - | Callback to authenticate the user. Returns user data. |
| Authorizer | `func(c *gin.Context, data any) bool` | No | `true` | Callback to authorize the authenticated user. |
| PayloadFunc | `func(data any) jwt.MapClaims` | No | - | Callback to add additional payload data to the token. |
| Unauthorized | `func(c *gin.Context, code int, message string)` | No | - | Callback for unauthorized requests. |
| LoginResponse | `func(c *gin.Context, token *core.Token)` | No | - | Callback for successful login response. |
| LogoutResponse | `func(c *gin.Context)` | No | - | Callback for successful logout response. |
| RefreshResponse | `func(c *gin.Context, token *core.Token)` | No | - | Callback for successful refresh response. |
| IdentityHandler | `func(*gin.Context) any` | No | - | Callback to retrieve identity from claims. |
| IdentityKey | `string` | No | `"identity"` | Key used to store identity in claims. |
| TokenLookup | `string` | No | `"header:Authorization"` | Source to extract token from (header, query, cookie). |
| TokenHeadName | `string` | No | `"Bearer"` | Header name prefix. |
| TimeFunc | `func() time.Time` | No | `time.Now` | Function to provide current time. |
| PrivKeyFile | `string` | No | - | Path to private key file (for RS algorithms). |
| PubKeyFile | `string` | No | - | Path to public key file (for RS algorithms). |
| SendCookie | `bool` | No | `false` | Whether to send token as a cookie. |
| CookieMaxAge | `time.Duration` | No | `Timeout` | Duration that the cookie is valid. |
| SecureCookie | `bool` | No | `false` | Whether to use secure cookies (HTTPS only). |
| CookieHTTPOnly | `bool` | No | `false` | Whether to use HTTPOnly cookies. |
| CookieDomain | `string` | No | - | Domain for the cookie. |
| CookieName | `string` | No | `"jwt"` | Name of the cookie. |
| CookieSameSite | `http.SameSite` | No | - | SameSite attribute for the cookie. |
| SendAuthorization | `bool` | No | `false` | Whether to return authorization header for every request. |
| DisabledAbort | `bool` | No | `false` | Disable abort() of context. |
| ParseOptions | `[]jwt.ParserOption` | No | - | Options for parsing the JWT. |

---

Expand Down Expand Up @@ -1082,3 +1082,11 @@ Signature: `func(c *gin.Context, token *core.Token)`
OPTIONAL `Unauthorized`:

On any error logging in, authorizing the user, or when there was no token or a invalid token passed in with the request, the following will happen. The gin context will be aborted depending on `DisabledAbort`, then `HTTPStatusMessageFunc` is called which by default converts the error into a string. Finally the `Unauthorized` function will be called. This function should likely return a JSON containing the http error code and error message to the user.

**Note:** When a 401 Unauthorized response is returned, the middleware automatically adds a `WWW-Authenticate` header with the `Bearer` authentication scheme, as defined in [RFC 6750](https://tools.ietf.org/html/rfc6750) (OAuth 2.0 Bearer Token Usage), [RFC 7235](https://tools.ietf.org/html/rfc7235) (HTTP Authentication), and the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401):

```txt
WWW-Authenticate: Bearer realm="<your-realm>"
```

This header informs HTTP clients that Bearer token authentication is required, ensuring compatibility with standard HTTP authentication mechanisms.
73 changes: 41 additions & 32 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,37 +358,37 @@ func helloHandler(c *gin.Context) {

`GinJWTMiddleware` 结构体提供以下配置选项:

| 选项 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| Realm | `string` | 否 | `"gin jwt"` | 显示给用户的 Realm 名称。 |
| SigningAlgorithm | `string` | 否 | `"HS256"` | 签名算法 (HS256, HS384, HS512, RS256, RS384, RS512)。 |
| Key | `[]byte` | 是 | - | 用于签名的密钥。 |
| Timeout | `time.Duration` | 否 | `time.Hour` | JWT Token 的有效期。 |
| MaxRefresh | `time.Duration` | 否 | `0` | 刷新 Token 的有效期。 |
| Authenticator | `func(c *gin.Context) (any, error)` | 是 | - | 验证用户的回调函数。返回用户数据。 |
| Authorizer | `func(c *gin.Context, data any) bool` | 否 | `true` | 授权已验证用户的回调函数。 |
| PayloadFunc | `func(data any) jwt.MapClaims` | 否 | - | 向 Token 添加额外 Payload 数据的回调函数。 |
| Unauthorized | `func(c *gin.Context, code int, message string)` | 否 | - | 处理未授权请求的回调函数。 |
| LoginResponse | `func(c *gin.Context, token *core.Token)` | 否 | - | 处理成功登录响应的回调函数。 |
| LogoutResponse | `func(c *gin.Context)` | 否 | - | 处理成功登出响应的回调函数。 |
| RefreshResponse | `func(c *gin.Context, token *core.Token)` | 否 | - | 处理成功刷新响应的回调函数。 |
| IdentityHandler | `func(*gin.Context) any` | 否 | - | 从 Claims 检索身份的回调函数。 |
| IdentityKey | `string` | 否 | `"identity"` | 用于在 Claims 中存储身份的键。 |
| TokenLookup | `string` | 否 | `"header:Authorization"` | 提取 Token 的来源(header, query, cookie)。 |
| TokenHeadName | `string` | 否 | `"Bearer"` | Header 名称前缀。 |
| TimeFunc | `func() time.Time` | 否 | `time.Now` | 提供当前时间的函数。 |
| PrivKeyFile | `string` | 否 | - | 私钥文件路径(用于 RS 算法)。 |
| PubKeyFile | `string` | 否 | - | 公钥文件路径(用于 RS 算法)。 |
| SendCookie | `bool` | 否 | `false` | 是否将 Token 作为 Cookie 发送。 |
| CookieMaxAge | `time.Duration` | 否 | `Timeout` | Cookie 的有效期。 |
| SecureCookie | `bool` | 否 | `false` | 是否使用安全 Cookie(仅限 HTTPS)。 |
| CookieHTTPOnly | `bool` | 否 | `false` | 是否使用 HTTPOnly Cookie。 |
| CookieDomain | `string` | 否 | - | Cookie 的域名。 |
| CookieName | `string` | 否 | `"jwt"` | Cookie 的名称。 |
| CookieSameSite | `http.SameSite` | 否 | - | Cookie 的 SameSite 属性。 |
| SendAuthorization | `bool` | 否 | `false` | 是否为每个请求返回授权 Header。 |
| DisabledAbort | `bool` | 否 | `false` | 禁用 context 的 abort()。 |
| ParseOptions | `[]jwt.ParserOption` | 否 | - | 解析 JWT 的选项。 |
| 选项 | 类型 | 必填 | 默认值 | 描述 |
| ----------------- | ------------------------------------------------ | ---- | ------------------------ | ----------------------------------------------------- |
| Realm | `string` | 否 | `"gin jwt"` | 显示给用户的 Realm 名称。 |
| SigningAlgorithm | `string` | 否 | `"HS256"` | 签名算法 (HS256, HS384, HS512, RS256, RS384, RS512)。 |
| Key | `[]byte` | 是 | - | 用于签名的密钥。 |
| Timeout | `time.Duration` | 否 | `time.Hour` | JWT Token 的有效期。 |
| MaxRefresh | `time.Duration` | 否 | `0` | 刷新 Token 的有效期。 |
| Authenticator | `func(c *gin.Context) (any, error)` | 是 | - | 验证用户的回调函数。返回用户数据。 |
| Authorizer | `func(c *gin.Context, data any) bool` | 否 | `true` | 授权已验证用户的回调函数。 |
| PayloadFunc | `func(data any) jwt.MapClaims` | 否 | - | 向 Token 添加额外 Payload 数据的回调函数。 |
| Unauthorized | `func(c *gin.Context, code int, message string)` | 否 | - | 处理未授权请求的回调函数。 |
| LoginResponse | `func(c *gin.Context, token *core.Token)` | 否 | - | 处理成功登录响应的回调函数。 |
| LogoutResponse | `func(c *gin.Context)` | 否 | - | 处理成功登出响应的回调函数。 |
| RefreshResponse | `func(c *gin.Context, token *core.Token)` | 否 | - | 处理成功刷新响应的回调函数。 |
| IdentityHandler | `func(*gin.Context) any` | 否 | - | 从 Claims 检索身份的回调函数。 |
| IdentityKey | `string` | 否 | `"identity"` | 用于在 Claims 中存储身份的键。 |
| TokenLookup | `string` | 否 | `"header:Authorization"` | 提取 Token 的来源(header, query, cookie)。 |
| TokenHeadName | `string` | 否 | `"Bearer"` | Header 名称前缀。 |
| TimeFunc | `func() time.Time` | 否 | `time.Now` | 提供当前时间的函数。 |
| PrivKeyFile | `string` | 否 | - | 私钥文件路径(用于 RS 算法)。 |
| PubKeyFile | `string` | 否 | - | 公钥文件路径(用于 RS 算法)。 |
| SendCookie | `bool` | 否 | `false` | 是否将 Token 作为 Cookie 发送。 |
| CookieMaxAge | `time.Duration` | 否 | `Timeout` | Cookie 的有效期。 |
| SecureCookie | `bool` | 否 | `false` | 是否使用安全 Cookie(仅限 HTTPS)。 |
| CookieHTTPOnly | `bool` | 否 | `false` | 是否使用 HTTPOnly Cookie。 |
| CookieDomain | `string` | 否 | - | Cookie 的域名。 |
| CookieName | `string` | 否 | `"jwt"` | Cookie 的名称。 |
| CookieSameSite | `http.SameSite` | 否 | - | Cookie 的 SameSite 属性。 |
| SendAuthorization | `bool` | 否 | `false` | 是否为每个请求返回授权 Header。 |
| DisabledAbort | `bool` | 否 | `false` | 禁用 context 的 abort()。 |
| ParseOptions | `[]jwt.ParserOption` | 否 | - | 解析 JWT 的选项。 |

---

Expand Down Expand Up @@ -1008,6 +1008,7 @@ CookieSameSite: http.SameSiteDefaultMode, // SameSiteDefaultMode, SameSiteLaxM
将认证通过的用户数据转为 `MapClaims`(map[string]any),必须包含 `IdentityKey`(默认 `"identity"`)。

**标准 JWT Claims(RFC 7519):** 您可以在 `PayloadFunc` 中设置标准 JWT claims 以提高互操作性:

Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This blank line appears to be added unnecessarily in the middle of a documentation section. It disrupts the flow between the introductory text about JWT claims and the bulleted list. Consider removing this extra blank line to maintain consistent documentation formatting.

Suggested change

Copilot uses AI. Check for mistakes.
- `sub`(Subject)- 用户标识符(例如用户 ID)
- `iss`(Issuer)- Token 签发者(例如您的应用程序名称)
- `aud`(Audience)- 预期的接收方(例如您的 API)
Expand Down Expand Up @@ -1083,5 +1084,13 @@ CookieSameSite: http.SameSiteDefaultMode, // SameSiteDefaultMode, SameSiteLaxM

### 登录失败、Token 错误或权限不足

- **可选:** `Unauthorized`
- **可选:** `Unauthorized`
处理登录、授权或 Token 错误时的响应。返回 HTTP 错误码与消息的 JSON。

**注意:** 当返回 401 Unauthorized 响应时,中间件会自动添加 `WWW-Authenticate` 标头,使用 `Bearer` 认证方案,符合 [RFC 6750](https://tools.ietf.org/html/rfc6750)(OAuth 2.0 Bearer Token 使用规范)、[RFC 7235](https://tools.ietf.org/html/rfc7235)(HTTP 认证框架)和 [MDN 文档](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401)的要求:

```txt
WWW-Authenticate: Bearer realm="<your-realm>"
```

该标头告知 HTTP 客户端需要 Bearer Token 认证,确保与标准 HTTP 认证机制的兼容性。
Loading
Loading