【问题标题】:401 error when accessing MusicKit API via node.js通过 node.js 访问 MusicKit API 时出现 401 错误
【发布时间】:2019-05-20 23:00:07
【问题描述】:

我正在尝试访问 MusicKit API,但它不断返回 401 未经授权的错误。我想不通。我有这个代码来生成一个开发者令牌:

const privateKey = fs.readFileSync("resources/AuthKey.p8").toString();  
  const teamId = "MYTEAMID";  
  const keyId = "MYKEYID";  

  const options = {  
    algorithm: "ES256",  
    expiresIn: "180d",  
    issuer: "MYTEAMID", // your 10-character Team ID, obtained from your developer account  
    header: {  
      alg: "ES256",  
      kid: "MYKEYID", // your MusicKit Key ID  
    },  
  };  

  return new Promise((resolve: any, reject: any) => {  
    jwt.sign({}, privateKey, options, (error, token) => {  
      if (error) {  
        return reject(error);  
      } else { // token created  
        return resolve(token);  
      }  
    });  
  });  

这会生成一个成功的令牌。解码后,此令牌的标头具有如下值:

{  
 "alg": "ES256",  
 "typ": "JWT",  
 "kid": "MYKEYID"  
}  

以及像这样的有效载荷值:

{  
 "iat": 1558197586,  
 "exp": 1573749586,  
 "iss": "MYTEAMID"  
}  

我知道 Apple 没有在标题中指定 typ,所以这可能是个问题吗?

然后,我尝试在 curl 请求中对像 curl -v -H 'Authorization: Bearer <MYTOKEN>' "https://api.music.apple.com/v1/catalog/us/artists/36954" 这样的示例艺术家使用它,但它返回 401 错误:

Trying 23.13.216.88...  
* TCP_NODELAY set  
* Connected to api.music.apple.com (23.13.216.88) port 443 (#0)  
* ALPN, offering h2  
* ALPN, offering http/1.1  
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH  
* successfully set certificate verify locations:  
*   CAfile: /etc/ssl/cert.pem  
 CApath: none  
* TLSv1.2 (OUT), TLS handshake, Client hello (1):  
* TLSv1.2 (IN), TLS handshake, Server hello (2):  
* TLSv1.2 (IN), TLS handshake, Certificate (11):  
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):  
* TLSv1.2 (IN), TLS handshake, Server finished (14):  
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):  
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):  
* TLSv1.2 (OUT), TLS handshake, Finished (20):  
* TLSv1.2 (IN), TLS change cipher, Client hello (1):  
* TLSv1.2 (IN), TLS handshake, Finished (20):  
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384  
* ALPN, server accepted to use h2  
* Server certificate:  
*  subject: businessCategory=Private Organization; jurisdictionCountryName=US; jurisdictionStateOrProvinceName=California; serialNumber=C0806592; C=US; ST=California; L=Cupertino; O=Apple Inc.; OU=Internet Services for Akamai; CN=itunes.apple.com  
*  start date: May  1 00:00:00 2019 GMT  
*  expire date: May  1 12:00:00 2020 GMT  
*  subjectAltName: host "api.music.apple.com" matched cert's "api.music.apple.com"  
*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 Extended Validation Server CA  
*  SSL certificate verify ok.  
* Using HTTP2, server supports multi-use  
* Connection state changed (HTTP/2 confirmed)  
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0  
* Using Stream ID: 1 (easy handle 0x7ff42a004600)  
> GET /v1/catalog/us/artists/36954 HTTP/2  
> Host: api.music.apple.com  
> User-Agent: curl/7.54.0  
> Accept: */*  
> Authorization: Bearer eyJh...
>  
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!  
< HTTP/2 401  
< content-type: application/json; charset=utf-8  
< access-control-allow-origin: *  
< strict-transport-security: max-age=31536000; includeSubDomains  
< date: Sat, 18 May 2019 16:33:58 GMT  
< x-cache: TCP_MISS from a104-117-183-52.deploy.akamaitechnologies.com (AkamaiGHost/9.6.4.1-25700704)   
<  
* Connection #0 to host api.music.apple.com left intact  

为什么???

【问题讨论】:

    标签: javascript node.js apple-musickit


    【解决方案1】:

    不确定您使用的是哪个jwt 库以及是否正确使用。

    这对我有用:

    const jwt = require('jsonwebtoken');
    const fs = require('fs')
    
    const APNS_KEY_ID = 'XXXXXXXXXXX'
    const TEAM_ID = 'XXXXXXXXXXX'
    
    const TWENTY_FOUR_HOURS = 1000 * 60 * 60 * 24;
    const privateKey = fs.readFileSync("keys/AuthKey.p8").toString();
    
    const generateToken = () => {
      var now = new Date();
      var tomorrow = new Date(now.getTime() + TWENTY_FOUR_HOURS);
      token = jwt.sign({
        'iss': TEAM_ID,
        'iat': Math.floor(now / 1000),
        'exp': Math.floor(tomorrow / 1000)
      }, privateKey, { algorithm: 'ES256', 'keyid': APNS_KEY_ID})
      console.log('Apple token generated', token)
      return token
    }
    generateToken()
    

    测试:

    curl -X GET \
      'https://api.music.apple.com/v1/catalog/us/search?term=drake&types=songs&limit=1' \
      -H 'Authorization: Bearer eyJh...'
    

    【讨论】:

    • 感谢您的回答,但它对我不起作用 :( 我只是不知道出了什么问题。我使用的 jsonwebtoken 库和你一样。跨度>
    • 我可以使用我的令牌生成很好地调用“模拟太多错误”端点,它给了我正确的 429 错误代码,但不是实际的端点
    • 也许可以试试更短的exp。我认为 180 是最大值。
    • 我试过了,我试过你的代码,它就是行不通。你能给我一个你为我生成的令牌的例子吗?
    • 我用我的令牌和你的(来自你的 sn-p)尝试了相同的 cURL 命令。适用于我的而不是您的。唯一的区别是kidissiatexp,这是预期的。也许为 MusicKit 服务重新生成你的私钥 (developer.apple.com/account/ios/authkey)。应该是一个 3 行文件。
    猜你喜欢
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    相关资源
    最近更新 更多