golang jwt使用
golang jwt使用中遇到的一个坑,特此记录。

具体描述:因为公司需要,现有架构jwt生成token的代码是java实现的,然后现在在golang中需要对此token进行解析。
java 用到的jar包: io.jsonwebtoken.jjwt 0.9.0
golang 用到的库:github.com/dgrijalva/jwt-go

java生成token测试代码如下:

public static void main(String[] args) {
String tokenSecretKey="whatthefuck123weishenmebuneng123"; //密钥
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("iss", "doubles"); //有好几个变量,具体看类Claims

String token = Jwts.builder()
.setHeaderParam("typ", "JWT") //设置头参数
.setClaims(claims) //设置内容对象
.signWith(SignatureAlgorithm.HS256, tokenSecretKey) //设置加密方式和传入密钥
.compact(); //生成token
System.out.println(token); //eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkb3VibGVzIn0.cBDFVLuQZV2B7J76kk17LE2hmni_3RbzTBzIH_OsriE(测试token)
}
1
2
3
4
5
6
7
8
9
10
11
12
golang解析token获取claims测试代码如下:

func TestParseAuthToken(t *testing.T) {
mySignKey := []byte("whatthefuck123weishenmebuneng123") //密钥,同java代码,需要注意的就是这里
token := "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkb3VibGVzIn0.cBDFVLuQZV2B7J76kk17LE2hmni_3RbzTBzIH_OsriE" //java生成的token
parseAuth, err := jwt.Parse(token, func(*jwt.Token) (interface{}, error) { //调用jwt,parse解析token
return mySignKey, nil
})
if err != nil {
fmt.Println("parase with claims failed.", err)
return
}
fmt.Println("还原后的token信息claims部分:", parseAuth.Claims)
}
1
2
3
4
5
6
7
8
9
10
11
12
golang用这段代码解析token,最终会报parase with claims failed. signature is invalid错误。

经过查看java和golang的源码,发现提示错误部分在一下代码中。

//验证token的前两段和key加密后是否与第三段相等
if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
vErr.Inner = err
vErr.Errors |= ValidationErrorSignatureInvalid
}
1
2
3
4
5
在进入方法中查看,发现java从string转成byte数组是用us-ascii编码,而golang默认是utf-8,一开始以为是这个问题,所以一直纠结在这里,想着重写DecodeSegment和EncodeSegment,但是发现hmac加密后的字节数组一直是对不上的。后来再仔细查看了下java中加密的源码,发现在设置加密方式和传入密钥(signWith(SignatureAlgorithm.HS256, tokenSecretKey))这里对密钥的处理方式是TextCodec.BASE64.decode(base64EncodedSecretKey),但是我在golang的代码中是直接对字符串进行转化字节数组,我估计这里会有问题,所以也将key的转化格式改成mySignKeyBytes, err := base64.URLEncoding.DecodeString(“whatthefuck123weishenmebuneng123”)再进行测试,这时候竟然就通过了!所以最后定位就是这个问题。

最后附上最终的golang代码。

func TestParseAuthToken(t *testing.T) {
mySignKey := "whatthefuck123weishenmebuneng123" //密钥,同java代码
mySignKeyBytes, err := base64.URLEncoding.DecodeString(mySignKey) //需要用和加密时同样的方式转化成对应的字节数组
if err != nil {
fmt.Println("base64 decodeString failed.", err)
return
}
token := "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkb3VibGVzIn0.cBDFVLuQZV2B7J76kk17LE2hmni_3RbzTBzIH_OsriE" //token
parseAuth, err := jwt.Parse(token, func(*jwt.Token) (interface{}, error) {
return mySignKeyBytes, nil
})
if err != nil {
fmt.Println("parase with claims failed.", err)
return
}
fmt.Println("还原后的token信息claims部分:", parseAuth.Claims)
}
————————————————
版权声明:本文为CSDN博主「qiang527052」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qiang527052/java/article/details/80748700

分类:

技术点:

相关文章: