dongshen9058 2013-04-24 08:51
浏览 1154
已采纳

如何验证JWT签名?

I want to authenticate Android users with a Go AppEngine backend,

I can easily get an ID-token in Android by following http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html

the ID-token payload can be verified with the oauth2/v2 package of the https://code.google.com/p/google-api-go-client/ library.

some installation tweaks are necessary for using it with AppEngine, I found some pointers at http://golangtutorials.blogspot.co.il/2011/11/using-external-api-in-go-appengine.html

according to the doc: "Verify Signature It turns out that this is signed using a Google public/private key pair, and Google publishes the public keys (which we change regularly) at www.googleapis.com/oauth2/v1/certs; go ahead and have a look.

You have to verify that the ID Token, which is actually a JSON Web Token, was signed with one of those certs. Fortunately, there are decent libraries around to do this; in this post, I’ll give pointers for Java, Ruby, and PHP.

The libraries can cache the Google certs and only refresh them when required, so the verification is (almost always) a fast static call."

how do I verify in Go that the token was signed by Google?

  • 写回答

2条回答 默认 最新

  • dsgrs26202 2013-07-14 14:33
    关注

    this is what I ended up doing (using https://github.com/dgrijalva/jwt-go):

    package XXX
    
    import (
        "errors"
        oauth2 "code.google.com/p/google-api-go-client/oauth2/v2"
        "jwt"
        "appengine"
        "appengine/urlfetch"
    )
    
    func getTokeninfo(c appengine.Context, token string) (*oauth2.Tokeninfo, error) {
        client := urlfetch.Client(c)
    
        oauth2Svc, err := oauth2.New(client) 
    
        if err != nil {
            return nil, err
        }
    
        return oauth2Svc.Tokeninfo().Id_token(token).Do()
    }
    
    func verifyToken(c appengine.Context, token string) (string, error) {
        parsedToken, err := jwt.Parse(token)
    
        if err != nil {
            c.Debugf(err.Error())
            return "", err
        }
    
        if parsedToken.Claims["aud"] != "XXX.apps.googleusercontent.com" {
            c.Debugf("aud mismatch")
            return "", errors.New("Aud mismatch")
        }
    
        if (parsedToken.Claims["azp"] != "XXX.apps.googleusercontent.com") && 
            (parsedToken.Claims["azp"] != "XXX.apps.googleusercontent.com") {
    
            c.Debugf("azp mismatch")
            return "", errors.New("Azp mismatch")
        }
    
        ti, err := getTokeninfo(c, token)
    
        if err != nil {
            c.Debugf(err.Error())
            return "", err
        }
    
        if (ti.Issued_to != "XXX.apps.googleusercontent.com") &&
            (ti.Issued_to != "XXX.apps.googleusercontent.com") {
    
            c.Debugf("cid mismatch")
            return "", errors.New("Client ID mismatch")
        }
    
        return ti.User_id, nil
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 求帮我调试一下freefem代码
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图