JWT

什么是JWT

Json Web Tokens(JWT),是为了在网络应用环境间传递声明而执行的一种给予JSON的开放标准。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息。

如何使用JWT

如果开启了JWT开关,则每个请求需要包含token信息让TronGrid进行验证,未通过验证的请求将不予响应,每个账号最多可以创建3个JWT,创建JWT时需要填入用户创建的公钥(现在支持的是RS256),填入公钥后会产生ID和Fingerprint。

示例

1.生成RSA密钥对

为了在项目中使用JWT,首先需要生成一个公钥/私钥对。Trongrid目前支持算法RS256。请确保将私钥保密!

openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

您需要输入易于理解的名称来标识密钥,以及密钥文件中的文本。它应该是PEM编码的文件(例如,由OpenSSL生成)。通常看起来像这样:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvGek2v/H/TEzB+mnfbJ5
m7wgon0u/JjFQY3kYr6E0N4cRBQm8sy6ikNKi5x/1YxmhBqn6HvF9xD/p72eCBVe
RFh863pjWpF1C5yjOq3OEks00ayRP1ukATG8LtoUnWoPisXrh5/wVe4fHDPeNwe4
5RXOp6svO860o/ckAxt8yO/ZczqtN8cNA7unGawJ3cn8VeL+pa4a6f8DNfp32QUY
Y//HjPFvrTxcfJ4cM6E74L913P2CDuiSVVXMk0iyX/blh6M4h7dGAlcmHEHno9OW
5jrrAKobZZT1quc6qT43sTJviqc24Ndgas5jTOPhEV7bgkgQbTbtpgorHjUpqAIm
+wIDAQAB
-----END PUBLIC KEY-----

2 生成token

方法一 使用java代码

引入jjwt包

compile 'io.jsonwebtoken:jjwt-api:0.11.2'
runtime 'io.jsonwebtoken:jjwt-impl:0.11.2'
runtime 'io.jsonwebtoken:jjwt-jackson:0.11.2'

调用createSignedJwtRsa256生成token

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.spongycastle.util.encoders.Base64;
  
public class JwtTest {
  
 private static PublicKey getRSAPublicKey(String inputKey)
    throws NoSuchAlgorithmException, InvalidKeySpecException {
  String rsaPublicKey = inputKey.replace("-----BEGIN PUBLIC KEY-----", "");
  rsaPublicKey = rsaPublicKey.replace("-----END PUBLIC KEY-----", "");
  rsaPublicKey = rsaPublicKey.replace("\n", "");
 
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(rsaPublicKey));
  KeyFactory kf = KeyFactory.getInstance("RSA");
  return kf.generatePublic(keySpec);
 }
 
 
public void createSignedJwtRsa256() {
  /**
   * {
   *   "alg": "RS256",
   *   "typ": "JWT",
   *   "kid": "bdbd8dabcb8d49f3ae9732c14c9940ea"
   * }
   *
   * {
   *   "exp": 1617736153,
   *   "aud": "trongrid.io",
   * }
   * */
 
  try {
    PrivateKey privateKey = getRSAPrivateKey(privateKeyStr);
 
    JwtBuilder builder = Jwts.builder()
        .setHeaderParam("alg", "RS256") // 固定值
        .setHeaderParam("typ", "JWT") // 固定值
        .setHeaderParam("kid", "XXXXXXXXXXX") // your jwt key id
        .claim("exp", 1617736153) // 过期时间
        .claim("aud", "trongrid.io") // 固定值
        .signWith(privateKey, SignatureAlgorithm.RS256);
 
    String token = builder.compact();
    System.out.println(token);
 
  } catch (Exception e) {
    e.printStackTrace();
    assert false;
  }
}
  
}

方法二 使用jwt网页

1 打开网址:https://jwt.io/

2 选择RSA256算法

3 输入header,其中kid为JWT的id,在为API Key添加JWT后,从API Key配置中查看

{ "alg": "RS256",
 "typ": "JWT",
  "kid": "XXXXXXX" // jwt的id
}

4 输入playload,exp为未过期时间,可不填写。

{
  "exp": "1617736153",
  "aud": "trongrid.io"  
}

5 在VERIFY SIGNATURE 一栏中,分别输入公钥和私钥

6 在ENCODED一栏,则可以看到生成的token

3 使用token

在请求header中,增加Authorization 字段,其值为:Bearer XXXXXX。
其中XXXX为token,token和Bearer中间有一个空格。

示例

curl -X POST \
  https://api.trongrid.io/wallet/createtransaction \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer xxxxxx' \
  -H 'TRON-PRO-API-KEY: 25f66928-0b70-48cd-9ac6-da6f8247c663' \
  -d '{
    "to_address": "41e9d79cc47518930bc322d9bf7cddd260a0260a8d",
    "owner_address": "41D1E7A6BC354106CB410E65FF8B181C600FF14292",
    "amount": 1000
}'
import requests

url = "https://api.trongrid.io/wallet/createtransaction"

payload = "{\n    \"to_address\": \"41e9d79cc47518930bc322d9bf7cddd260a0260a8d\",\n    \"owner_address\": \"41D1E7A6BC354106CB410E65FF8B181C600FF14292\",\n    \"amount\": 1000\n}"
headers = {
    'Authorization': "Bearer xxxxxx",
    'Content-Type': "application/json",
    'TRON-PRO-API-KEY': "25f66928-0b70-48cd-9ac6-da6f8247c663"
    }
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
var request = require("request");

var options = { method: 'POST',
  url: 'https://api.trongrid.io/wallet/createtransaction',
  headers: {  
     'Authorization': 'Bearer xxxxxx',
     'TRON-PRO-API-KEY': '25f66928-0b70-48cd-9ac6-da6f8247c663',
     'Content-Type': 'application/json' 
},
  body: { 
      to_address: '41e9d79cc47518930bc322d9bf7cddd260a0260a8d',
     owner_address: '41D1E7A6BC354106CB410E65FF8B181C600FF14292',
     amount: 1000 
},
  json: true 
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

4 注意事项

header中的"typ"固定为"JWT"。
目前只支持RS256,ES256会在后期版本中增加支持。所以在header中的alg字段目前固定为RS256。
playload中的"aud"固定为"trongrid.io"。

//Header:
{
    "alg": "RS256",
    "typ": "JWT",
    "kid": "bdbd8dabcb8d49f3ae9732c14c9940ea"  // your jwt id
}

//Body
{
  "exp": 1617736153,
  "aud": "trongrid.io"
}