Hi @naz and thanks for your quick reply as I am getting a bit tired not being able to sort it out.
I use the latest version of ghost:3.41.3-alpine
running with Docker 5:19.03.13~3-0~debian-buster
.
I have a retrofit HTTP client (Java) and I use com.auth0:java-jwt:3.13.0
to sign the JWT.
My configuration is as follow :
First, I want to say I’ve read multiple times :
My server is in Java, and this is my snippet:
public GhostBlogAdminApiService createAdminService(GhostBlog blog) throws DecoderException {
String adminApiKeId = blog.getAdminApiKey().split(":")[0];
String adminApiKeySecret = blog.getAdminApiKey().split(":")[1];
byte[] keyBytes = Hex.decodeHex(adminApiKeySecret.toCharArray());
Algorithm algorithm = Algorithm.HMAC256(keyBytes);
Map<String, Object> headerClaims = new HashMap<>();
headerClaims.put("typ", "JWT");
headerClaims.put("alg", "HS256");
headerClaims.put("kid", adminApiKeId);
Date now = new Date();
Date in5min = DateUtils.addMinutes(now, 5);
String token = JWT.create()
.withHeader(headerClaims)
.withIssuer("auth0")
.withIssuedAt(now)
.withExpiresAt(in5min)
.withAudience("/v3/admin/")
.sign(algorithm);
try {
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("auth0")
.build(); // Reusable verifier instance
DecodedJWT jwt = verifier.verify(token);
System.out.println(jwt.toString()); // <--- I always verify the signature without exception
} catch (JWTVerificationException exception){
// Invalid signature/claims
}
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC);
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(blog.getUrl() + "/ghost/api/v3/admin/")
.addConverterFactory(JacksonConverterFactory.create());
httpClient.interceptors().clear();
httpClient.addInterceptor(logging);
httpClient.interceptors().add(chain -> {
Request request = chain.request();
Headers headers = request.headers().newBuilder().add("Authorization", "Ghost " + token).build();
request = request.newBuilder().headers(headers).build();
return chain.proceed(request);
});
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(GhostBlogAdminApiService.class);
}
This is the retrofit GhostBlogAdminApiService
interface I use :
public interface GhostBlogAdminApiService {
@Headers({
"Accept: application/json; charset=utf-8",
"Content-Type: application/json; charset=utf-8",
})
@GET("site")
Call<GhostResponse.Admin.Site> getSite();
@Headers({
"Accept: application/json; charset=utf-8",
"Content-Type: application/json; charset=utf-8",
})
@POST("webooks/")
Call<GhostResponse.Admin.Webhooks> createWebHook(
@Body GhostAdminWebhook body
);
}
I’ve helped my self with this SO question without success
Using the signed token, no matter if I can verify it or not, I keep having 404
response code when I hit POST
on /ghost/api/v3/admin/webhooks
.
I’ve tested the insecure ghost/api/v3/admin/site
endpoint and it works great (so does all content endpoints), but site
admin route is without authentication.
I multiple checked the called endpoint and there’s absolutely no mistake in it :
My Ghost blog is hosted behind a Traefik V2 HTTPS
(let’s encrypt) reverse proxy and it worked so far for serving the website (perhaps not with the API?), please ask if you need this part of my configuration.
- Why do I have 404 and the person in this question is having 401?
- How did I fail?
- How can I get going with the
webhooks
admin API?