Go 认证与授权(Authentication)

12 篇文章 0 订阅
本文探讨了在不同编程语言和框架(如Python的Flask-JWT、Java的自定义注解、.NET的Attribute以及Go的原生和Gin中间件)中实现用户认证和权限控制的方法,强调了理解和正确使用这些技术的重要性。
摘要由CSDN通过智能技术生成

场景

我们应用开发经常会遇到认证和授权问题,比如:ERP系统、OA系统、CRM系统等等,这些系统都需要用户登录后才能访问,如何实现用户登录和权限认证呢?

我们来看下对应的解决方案:

Python的装饰器模式

熟悉Python的大小朋友可能都知道Flask-JWT这个flask的extension,如何使用的?

@jwt_required()
@app.route('/user/list')
def user_list():
    return users

COPY

Java中认证授权

Java的认证和授权主要有以下3中方式:

  1. 放到应用Gateway去做
  2. 自定义注解,类似于Python的Decorator
  3. 自定义拦截器

.NET的方式


[Authorize(Roles = "Admin")]
public class UserController : Controller 
{
    [Route("api/users")]
    public IActionResult Get()
    {
        return Ok(new { message = "Hello World" });
    }
}

COPY

问题

  1. 可能会忘记使用注解或者把他们放错位置
  2. 阅读业务代码需要理解注解的意思
  3. 找不到注解的定义
  4. 控制流程被隐藏

解决方案

原生Go Http Server

Go的解决方案也比较简单,

首先定义一个认证包装器


func Authentication(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 校验
        if !IsAuthenticated(r) {
            http.Error(w, "Not authenticated", http.StatusForbidden)
            return
        }
        h.ServeHTTP(w, r)
    }
}

COPY

然后使用它:


Authentication(http.HandlerFunc(w http.ResponseWriter,r *http.Response){
    // 处理请求
})

COPY

最后注册路由:


serve := http.NewServeMux()

// 需要验证的路由
serve.Handle("/",Authentication(http.HandlerFunc(w http.ResponseWriter,r *http.Response){
}))

// 不需要验证的路由
serve.Handle("/login",http.HandlerFunc(w http.ResponseWriter,r *http.Response){
})

COPY

基于Gin的认证

也是基于中间件的认证,和上面一样,只是使用gin框架。
也是首先定义一个Authentication中间件,然后注册路由的时候使用AuthMiddleware中间件。

func AuthMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        tokenStr := c.GetHeader("Authorization")
        if tokenStr == "" {
            c.JSON(http.StatusUnauthorized, common.CommonResp{
                Message: "Unauthorized",
            })
            c.Abort()
            return
        }

        token, err := jwt.ParseWithClaims(tokenStr, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
            if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
                return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
            }
            return []byte("secret"), nil
        })

        if err != nil {
            c.JSON(http.StatusUnauthorized, common.CommonResp{
                Message: "Unauthorized",
            })
            c.Abort()
        }

        if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
            // 添加claims到上下文
            c.Set("claims", claims)
            c.Next()
        } else {
            c.JSON(http.StatusUnauthorized, common.CommonResp{
                Message: "Unauthorized",
            })
            c.Abort()
        }

    }
}

COPY

然后定义一个Public和protect group来分别处理公共接口和需要登录的接口。


v1 := r.Group("/api/v1")

publicGroup := v1.Group("/")

protectGroup := v1.Group("/")
protectGroup.Use(user.AuthMiddleware())

user.InitRouter(publicGroup, protectGroup)

COPY

总结

处理认证和授权是业务系统场景的问题,不论你是在云上还是哪儿,同事各种编程语言和框架都会提供相应的解决方案,如Python的Flask-JWT, Java的自定义注解或拦截器,.NET的Attribute等。

无论使用哪种方法,都需要对相关的技术有深入的理解,并且在编程时要时刻注意,防止忘记使用注解,或者把注解放错位置。
阅读包含大量注解的代码也会变得困难,找不到注解的定义,或者感觉控制流程被隐藏起来了。

Go语言提供了更简洁清晰的解决方案。Go允许我们直接定义一个认证处理器并将其附加到注册路由上。我们可以自定义这个认证处理器,使其在进入handler之前进行预处理,校验请求是否已经过认证,以此实现权限控制。这样的设计使得控制流程变得清晰,且可以根据需要自由组合handler,具有很高的扩展性。

基于Gin的认证是另一种Go语言下的解决方案,借助于Gin框架,我们可以通过定义中间件的方式来处理认证问题。

参考

Go 认证与授权(Authentication) – 小厂程序员

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值