gozero 中间件获取 jwt 信息

jwt token 生成

// @secretKey: JWT 加解密密钥
// @iat: 时间戳
// @seconds: 过期时间,单位秒
// @payload: 数据载体
func getJwtToken(secretKey string, iat, seconds int64, payload int64) (string, error) {
	claims := make(jwt.MapClaims)
	claims["exp"] = iat + seconds
	claims["iat"] = iat
	claims["payload"] = payload
	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims = claims
	return token.SignedString([]byte(secretKey))
}

其他中间件获取 jwt 中信息

func (m *PermissionMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// TODO generate middleware implement function, delete after code implementation
		payload := r.Context().Value("payload")
		var userId int64
		if jsonPayload, ok := payload.(json.Number); ok {
			if int64UserId, err := jsonPayload.Int64(); err == nil {
				userId = int64UserId
				fmt.Println("当前用户ID: ", userId)
			} else {
				response.Response(w, nil, errors.New("用户信息获取失败"))
				return
			}
		} else {
			response.Response(w, nil, errors.New("用户信息获取失败"))
			return
		}
		// TODO 权限检查
		if true == false {
			response.Response(w, nil, errors.New("权限不足"))
			return
		}
		// Passthrough to next handler if need
		next(w, r)
	}
}

说明

  1. 可以看到中间件中可以直接 r.Context().Value("payload") 的形式获取我们在写入到 jwt 中的信息,注意这里的 payload 名称 和 jwt 设置的是保持一致的。这个 jwt 的解析过程在 gozero 的 jwt 组件中已经做了,所以我们可以方便的从 request 中获取。具体的jiwt 解析可以参考 gozero 的 rest/handler/authhandler.go ,可以看到已经通过 context.WithValue(ctx, k, v) 写入了值
parser := token.NewTokenParser()
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			tok, err := parser.ParseToken(r, secret, authOpts.PrevSecret)
			if err != nil {
				unauthorized(w, r, err, authOpts.Callback)
				return
			}

			if !tok.Valid {
				unauthorized(w, r, errInvalidToken, authOpts.Callback)
				return
			}

			claims, ok := tok.Claims.(jwt.MapClaims)
			if !ok {
				unauthorized(w, r, errNoClaims, authOpts.Callback)
				return
			}

			ctx := r.Context()
			for k, v := range claims {
				switch k {
				case jwtAudience, jwtExpire, jwtId, jwtIssueAt, jwtIssuer, jwtNotBefore, jwtSubject:
					// ignore the standard claims
				default:
					ctx = context.WithValue(ctx, k, v)
				}
			}

			next.ServeHTTP(w, r.WithContext(ctx))
		})
	}
  1. 我们在通过 payload := r.Context().Value("payload") 获取对应的值的类型,这个和我们设置 jwt token 是相关的,默认整个 jwt token 解析出来的是 json 的格式的,int/int64 写入 jwt 解析之后是 json.Number 类型,string 写入的话,解析出来的还是 string,所以获取值时需要有一个转换的过程。
在 .NET Core 中,可以通过 Microsoft.AspNetCore.Authentication.JwtBearer 包来实现 JWT 认证。以下是获取 JWT 用户身份信息的步骤: 1. 在 Startup.cs 文件的 ConfigureServices 方法中添加以下代码,来启用 JwtBearer 认证: ```csharp services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; }); ``` 2. 在 Configure 方法中添加以下代码,来启用认证中间件: ```csharp app.UseAuthentication(); ``` 3. 在需要获取用户身份信息的地方,可以使用以下代码来获取: ```csharp var identity = HttpContext.User.Identity as ClaimsIdentity; var userId = identity.FindFirst("userId")?.Value; ``` 上述代码会从当前请求的 HttpContext 中获取用户的身份信息,然后从中提取出 userId 的值。 需要注意的是,在生成 JWT 令牌时,需要将用户的身份信息添加到 Claims 中。例如: ```csharp var claims = new List<Claim> { new Claim("userId", user.Id.ToString()), new Claim(ClaimTypes.Name, user.UserName), // 其他用户信息的 Claim }; var token = new JwtSecurityToken( issuer: Configuration["Jwt:Issuer"], audience: Configuration["Jwt:Audience"], claims: claims, expires: DateTime.UtcNow.AddMinutes(30), signingCredentials: new SigningCredentials( new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])), SecurityAlgorithms.HmacSha256)); ``` 上述代码中,将 userId 添加到了 claims 列表中,生成 JWT 令牌时会将该信息加密存储,后续可以通过 HttpContext.User.Identity 获取到该信息
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值