mirror of https://github.com/veypi/OneAuth.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.8 KiB
Go
66 lines
1.8 KiB
Go
//
|
|
// Copyright (C) 2024 veypi <i@veypi.com>
|
|
// 2025-07-24 15:27:31
|
|
// Distributed under terms of the MIT license.
|
|
//
|
|
|
|
package oauth
|
|
|
|
import (
|
|
"github.com/veypi/OneAuth/cfg"
|
|
"github.com/vyes-ai/vigo"
|
|
)
|
|
|
|
// RevokeRequest 撤销令牌请求参数
|
|
type RevokeRequest struct {
|
|
Token string `form:"token" binding:"required"`
|
|
TokenTypeHint string `form:"token_type_hint"` // access_token 或 refresh_token
|
|
ClientID string `form:"client_id"`
|
|
ClientSecret string `form:"client_secret"`
|
|
}
|
|
|
|
// RevokeResponse 撤销令牌响应
|
|
type RevokeResponse struct {
|
|
Message string `json:"message"`
|
|
Success bool `json:"success"`
|
|
}
|
|
|
|
// handleRevoke 处理OAuth撤销请求
|
|
func handleRevoke(x *vigo.X) error {
|
|
args := &RevokeRequest{}
|
|
if err := x.Parse(args); err != nil {
|
|
return vigo.NewError("参数解析失败").WithError(err).WithCode(400)
|
|
}
|
|
|
|
if args.Token == "" {
|
|
return vigo.NewError("令牌不能为空").WithCode(400)
|
|
}
|
|
|
|
db := cfg.DB()
|
|
|
|
// 根据OAuth 2.0规范,撤销令牌应该是幂等操作
|
|
// 即使令牌不存在也应该返回成功,这是为了防止信息泄露
|
|
var revoked = false
|
|
|
|
// 尝试撤销访问令牌
|
|
result := db.Model(&OAuthAccessToken{}).Where("token = ?", args.Token).Update("revoked", true)
|
|
if result.Error == nil && result.RowsAffected > 0 {
|
|
revoked = true
|
|
}
|
|
|
|
// 如果没有找到访问令牌,尝试撤销刷新令牌
|
|
if !revoked {
|
|
result = db.Model(&OAuthRefreshToken{}).Where("token = ?", args.Token).Update("revoked", true)
|
|
if result.Error == nil && result.RowsAffected > 0 {
|
|
revoked = true
|
|
}
|
|
}
|
|
|
|
// 根据OAuth 2.0规范,即使令牌不存在也返回成功
|
|
// 这样可以防止攻击者通过响应差异推断令牌是否存在
|
|
return x.JSON(&RevokeResponse{
|
|
Message: "令牌撤销成功",
|
|
Success: true,
|
|
})
|
|
}
|