java生成Ghost博客系统的jwt token

2 篇文章 0 订阅

Ghost可以作为一个CMS系统,其提供了Admin API供调用,以接口方式实现对于系统的管理。
其Admin API接口使用两种认证方式:
token方式 认证适合服务端访问Ghost系统;
用户名/密码适合客户端访问。
由于自己是要做一个自定义的客户端工具,来由格式化的数据自动生成博客内容,因此使用用户名/密码方式和token的方式都可以。
Ghost系统,使用了标准的jwt标准的token,鉴于此尝试使用token来做认证。先先后后了解和学习了许多的内容,主要是在spring security体系下面jwt的应用。包括spring security提下下面基于oauth2协议的认证流程。

spring security下面基于OAuth2协议的认证方式目前还记得的大概是这么个流程:

  1. 用户访问资源中心,
  2. 资源中心检测到用户未携带有效的认证信息,将用户重定向到认证中心(同时将目标资源链接作为参数一同携带过去),
  3. 认证中心要求用户输入用户名/密码,验证有效后为目标资源链接生成一个一次性的code返回给用户,
  4. 用户使用这个code再请求认证中心获取到一个token(可以多次使用,但是有有效期),这个token中包含了用户必要信息包括用户名,授权资源信息等,由RSA私钥加密
  5. 用户携带token去访问资源中心,资源中心使用RSA公钥对token解密认证,获取其中携带的信息,如果符合相应资源的权限,则返回资源。同时如果检测到用户携带的token即将过期时,进行续期操作。
    这个应该就是jwt的认证方式,其中主要有用户、资源中心、认证中心三个角色。

言归正传,说回Ghost的jwt token来。Ghost提供了一个两段由冒号分割的Admin Key,前一段是id,后一段是16进制编码的secret。使用这两个信息对需要携带的token信息进行加密,Ghost即可认证,并解密出token中包含的信息。
按照Ghost官方的说法,需要三个步骤:

  1. 将admin key拆分成id和secret字符串
  2. 将secret进行16进制到byte[]的转换
  3. 使用选择的jwt工具库,利用id和转换过的secret,包含进要求的payload和header信息生成一个token即可。

但是自己研究的时候其实并不顺利,主要是auth0原生的jwt库的工具中没有HS256的加密算法,也不支持接收byte[]类型作为加密串。使用spring security的JwtHelper也有类似的问题,没有HS256的算法。
最后去网上找找,发现好几个帖子都在用一个jwt的工具库叫做jjwt,完整的依赖如下:

	    <groupId>io.jsonwebtoken</groupId>
        	<artifactId>jjwt</artifactId>
        	<version>0.9.1</version>
    	</dependency>

有了利器之后,一切都变得顺利起来,完整的生成token的代码如下:

	 public static void connectAsAdmin(String adminApiKey) throws Exception {
    //Split the API key by the : into an id and a secret
    String[] arr = adminApiKey.split(":");
    String id = arr[0];
    String secret = arr[1];
    //Decode the hexadecimal secret into the original binary byte array
    byte[] secretArr=hexToByte(secret);
    //Pass these values to your JWT library of choice, ensuring that the header and payload are correct.
    Map<String,Object> header=new HashMap<>();
    header.put("alg","HS256");
    header.put("kid",id);
    header.put("typ","JWT");
    Map<String,Object> payload=new HashMap<>();
    Long now= new Date().getTime()/1000;
    payload.put("iat",now);
    payload.put("exp",now+5*60);
    payload.put("aud","/v2/admin/");
    String token = Jwts.builder()
            .addClaims(payload)
            .setHeader(header)
            .signWith(SignatureAlgorithm.HS256,secretArr).compact();
    System.out.println(token);
}

其中有个16进制转换byte[]的方法hexToByte

  public static byte[] hexToByte(String hex){
        int m = 0, n = 0;
        int byteLen = hex.length() / 2; // 每两个字符描述一个字节
        byte[] ret = new byte[byteLen];
        for (int i = 0; i < byteLen; i++) {
            m = i * 2 + 1;
            n = m + 1;
            int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
            ret[i] = Byte.valueOf((byte)intVal);
        }
        return ret;
    }

这段代码,着实花了不少时间,两周?甚至一个月,也可能最近工作比较忙,也可能回家要忙着抱孩子,借口着实是不少。卡在这里这么久了,也是比较急,但是实际上只要用心去分析,用心去网上找,保持自己在一个较好的状态,实际上问题的解决都是个把小时的事情,关键是解决了问题,以及学习到了一些内容。
除了以上的接口,最近还读了几本书,包括一本《海明威传》《江*民传》,眼下还有一个《乌合之众》在看。同时还看了《烈火英雄》《哪吒之魔童归来》等等电影。
下面还有token的认证等,但是我的项目中token认证是由Ghost系统完成的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值