我正在使用中间件(CheckToken
)检查JWT并获取自定义声明(Id
)(它将是我的数据库中用户的ID)但我需要将其传递给campaign.Attack(所以我可以知道谁是正在进行“攻击”的用户),但我无法找到办法。
我尝试将其作为next(w, req, claim.id)
token.go
中的参数传递给我,但我需要触及http.HandlerFunc
函数,因此这不是一个有效选项。
关于如何将claim.id
从CheckToken
传递到campaign.Attack()
的任何想法?
谢谢
***** main.go*****
func main() {
router := mux.NewRouter()
router.HandleFunc("/attack", token.CheckToken(campaign.Attack)).Methods("GET", "OPTIONS")
log.Fatal(http.ListenAndServe(":3000", handlers.CORS(handlers.AllowedOrigins([]string{"*"}),
handlers.AllowedHeaders([]string{"Content-Type", "authorization"}))(router)))
}
******campaign.go*****
package campaign
import (
"log"
"net/http"
)
func init() {
}
func Attack(w http.ResponseWriter, req *http.Request) {
log.Println("attack")
//i need to get the claim.Id here
}
****token.go****
type MyCustomClaims struct {
Id int `json:"id"` //the Id of the user
jwt.StandardClaims
}
func CheckToken(next http.HandlerFunc) (MyCustomClaims, http.HandlerFunc) {
return MyCustomClaims{}, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
authorizationHeader := req.Header.Get("authorization")
if authorizationHeader != "" {
bearerToken := strings.Split(authorizationHeader, " ")
if len(bearerToken) == 2 {
token, err := jwt.ParseWithClaims(bearerToken[1], &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte("magicword"), nil
})
if token.Valid {
if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
//**************************
//***********i have the claims.id here and it works.*******
//**************************
log.Println(claims.Id)
//but i need to pass it or find a way to read it in campaign.Attack()
next(w, req)
} else {
log.Println(err)
}
} else if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
// Token is either expired or not active yet
}
}
}
}
})
}
答案 0 :(得分:0)
使用上下文的方法WithValue。 而是下一步(w,req)写
ctx := context.WithValue(r.Context(), "claim_id", claims.Id)
next(w, req.WithContext(ctx))
和内部攻击:
claim_id, ok := r.Context().Value("claim_id").(int)
if !ok {
return // I don't have context .. sorry
}
// use claim_id
我还没有提到,如何创建一个独特的密钥......但有时在未来。
答案 1 :(得分:0)
查看CheckToken ..它应该是中间件,典型的midleware传递http.Handler并且可能是另一个参数并返回另一个http.Handler(这比使用http.HandlerFunc好一点)。返回函数通常调用参数并在此调用之前或之后执行一些操作。
func CheckToken(next http.Handler) http.Handler
{
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// and body the same as you have in the answer, but instead of next(w, req) put there two lines "WithValue"
}
}
进入攻击的开始,接下来几行,我已经给你了