MusicKit Unable to login via JWT in Node

I'm trying to authenticate via JWT. I assume the claim is like


{ "alg": "ES256", "kid": "ABC123DEFG" } { "iss": "DEF123GHIJ", "iat": 1437179036, “exp”: 1493298100


Service.prototype.authenticate = function() {
    var self = this;
    return new Promise((resolve, reject) => {
        var cert = fs.readFileSync(self.options.cert); // get public key
        // sign asynchronously
        var claims = { // token claims payload


            //The issued at (iat) registered claim key, whose value indicates the time at which the token was generated,
            //in terms of the number of seconds since Epoch, in UTC
            iat: Math.floor(Date.now() / 1000),


            //The expiration time (exp) registered claim key,
            //whose value must not be greater than 15777000 (6 months in seconds) from the Current Unix Time on the server
            exp: Math.floor(Date.now() / 1000) + (60 * 60 * 24)


        };
        jwt.sign(claims,
            cert, {
                keyid: "ABC123DEFG",
                issuer: "DEF123GHIJ",
                algorithm: "ES256"
            },
            function(error, token) {
                if (error) return reject(error);
                else { // token created
                    var decoded = jwt.verify(token, cert);
                    console.log(decoded) // bar
                    self.token = token;
                    return resolve(token);
                }
            });
    });
} //authenticate



I get a JWT token from jwt.sign api, but after that the result is Unauthorized.
When I verify the token with the api jwt.verify the decoded token is


{ iat: 1496763987, exp: 1496850387 }



while it should contain the iss as well.
I'm not sure if this is a library issue - I'm using this node library or a authentication issue.

Accepted Reply

I had HTTP 401 as well. When I did dig, I found out I failed to generate token properly. Creating the token with the code from https://codegists.com/snippet/javascript/indexjs_aljs_javascript solved my problem.

Replies

I have improved the code above for the claims and options part:


var priv_key = fs.readFileSync( self.options.cert );
var claims = {
    iat: Math.floor( Date.now() / 1000 ),
    exp: Math.floor(Date.now() / 1000) + ( 60 * 60 * 24 )
};
var opts={
    keyid: self.options.kid,
    issuer: self.options.iss,
    algorithm: self.options.alg
};
jwt.sign(claims, priv_key, opts,
function(error, token) {
    if( error ) return reject(error);
    else { // token created
    return resolve(token);
    }
});


Actually I have a generated token, but it is not granted i.e. the server return

Unauthorized
:


{
    'content-type': 'text/plain; charset=UTF-8',
    server: 'kong/0.10.2', date: 'Mon, 12 Jun 2017 15:33:49 GMT',
    connection: 'close'
}


Not sure of, but I have found some issues on

kong
server when doing
jwt
sign in.

Is this a question about CloudKit or iCloud Drive? If not, I suspect you may not get much of a response here. There may be a better forum to ask this question, so if you can give more details about what you're trying to do then I can move the thread somewhere more appropriate.

I am also facing the similar issue. were you able to successfully generate the Developer Token for MusicKit. if so, please share the nodejs code.

Hey,


I am also getting an 'Unauthorized' and a status code of 401 when I make a call to the api.


401 is not even referenced on the possible codes page:

https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/AppleMusicWebServicesReference/HTTPStatusCodes.html#//apple_ref/doc/uid/TP40017625-CH50-SW1


I am not sure if the api is available yet for us to access? Any help or tips would be appreciated, thanks!

I use code from https://codegists.com/snippet/javascript/indexjs_aljs_javascript and the generated token is working OK with the API calls

I had HTTP 401 as well. When I did dig, I found out I failed to generate token properly. Creating the token with the code from https://codegists.com/snippet/javascript/indexjs_aljs_javascript solved my problem.

Hello, well since it's about MusicKit login, that uses the CloudKit oAuth, I can say that is about CloudKit plus MusicKit.

Thanks a lot!!! Your solution worked. This is the async version based on your solution:


var options = {
  algorithm: self.options.alg,
  expiresIn: "180d",
  issuer: self.options.iss, //your 10-character Team ID, obtained from your developer account
  header: {
  alg: self.options.alg,
  kid: self.options.kid, //your MusicKit Key ID
  }
  };
  jwt.sign({},
  cert,
  options,
  function(error, token) {
  if( error ) return reject(error);
  else { // token created
  self.token=token;
  return resolve(token);
  }
  });

Hey @bahrio, what about the logged-in APIs call - i.e. with the Music User Token?
For calls like the one you have tried in another post


$ echo $url
https://api.music.apple.com/v1/me/ratings/songs/1249510807
$ curl -H "Authorization: Bearer $token" -H "Music-User-Token: $userToken" $url



Did you managed to obrain the Music-User-Token server-side? In my knowledge there is CloudKit only server-side (node.js), but I do not see a way to generate such a token.