如何正确处理令牌刷新与Spotify SDK和Swift 3.错误代码= 3840

tl; dr我收到: JSON text did not start with array or object and option to allow fragments not set. 如果我试图收到一个令牌和No refresh token available in the session! 如果我试图更新令牌。

我试图在Swift 3中为Objective-C Spotify iOS SDK beta-25设置令牌刷新。我使用的是Heroku服务器,Spotify提供的Ruby脚本更改为我的凭据。

 require 'sinatra' require 'net/http' require 'net/https' require 'base64' require 'encrypted_strings' require 'json' CLIENT_ID = ENV['xxx'] CLIENT_SECRET = ENV['xxx'] ENCRYPTION_SECRET = ENV['xxx'] CLIENT_CALLBACK_URL = ENV['xxx://returnafterlogin'] AUTH_HEADER = "Basic " + Base64.strict_encode64(CLIENT_ID + ":" + CLIENT_SECRET) SPOTIFY_ACCOUNTS_ENDPOINT = URI.parse("https://accounts.spotify.com") get '/' do "Working" end post '/swap' do # This call takes a single POST parameter, "code", which # it combines with your client ID, secret and callback # URL to get an OAuth token from the Spotify Auth Service, # which it will pass back to the caller in a JSON payload. auth_code = params[:code] http = Net::HTTP.new(SPOTIFY_ACCOUNTS_ENDPOINT.host, SPOTIFY_ACCOUNTS_ENDPOINT.port) http.use_ssl = true request = Net::HTTP::Post.new("/api/token") request.add_field("Authorization", AUTH_HEADER) request.form_data = { "grant_type" => "authorization_code", "redirect_uri" => CLIENT_CALLBACK_URL, "code" => auth_code } response = http.request(request) # encrypt the refresh token before forwarding to the client if response.code.to_i == 200 token_data = JSON.parse(response.body) refresh_token = token_data["refresh_token"] encrypted_token = refresh_token.encrypt(:symmetric, :password => ENCRYPTION_SECRET) token_data["refresh_token"] = encrypted_token response.body = JSON.dump(token_data) end status response.code.to_i return response.body end post '/refresh' do # Request a new access token using the POST:ed refresh token http = Net::HTTP.new(SPOTIFY_ACCOUNTS_ENDPOINT.host, SPOTIFY_ACCOUNTS_ENDPOINT.port) http.use_ssl = true request = Net::HTTP::Post.new("/api/token") request.add_field("Authorization", AUTH_HEADER) encrypted_token = params[:refresh_token] refresh_token = encrypted_token.decrypt(:symmetric, :password => ENCRYPTION_SECRET) request.form_data = { "grant_type" => "refresh_token", "refresh_token" => refresh_token } response = http.request(request) status response.code.to_i return response.body end 

通过设置:

 SPTAuth.defaultInstance().tokenSwapURL = URL(string: SpotifyCredentials.tokenSwapURLSwap) SPTAuth.defaultInstance().tokenRefreshURL = URL(string: SpotifyCredentials.tokenSwapURLRefresh) 

现在用户无法再login,我收到上面的错误。 如果我删除tokenSwapURLtokenRefreshURL ,一切都会重新运行,但用户必须每60分钟重新授权一次。

如果我试图用已经login的用户刷新令牌,我会收到:

"No refresh token available in the session!"

 if SPTAuth.defaultInstance().session != nil { print("needs login") SPTAuth.defaultInstance().renewSession(SPTAuth.defaultInstance().session, callback: { error, session in if error != nil { print("\(error?.localizedDescription)") // "No refresh token available in the session!" return } }) } 

我错过了什么? 帮助非常感谢。

简短的总结:假设你的JSONparsing工作正常,问题是畸形的JSON(服务器端)。


JSON文本没有开始数组或对象和选项,以允许片段没有设置

可以通过返回的JSONSerialization.jsonObject(with:options:)引发

来自JSON数据的基础对象,或者

如果发生错误,则 nil

格式不正确的JSON» nil而不是令牌»当前令牌被取消»结果: “用户无法再login”

获取格式错误的JSON的可能的解释包括:

通常是因为某些警告消息从您的服务器中抛出,而没有放入响应数组中。 例如在PHP中,一些“警告消息”没有被捕获到数组中,所以当你最终使用“echo json_encode($ RESPONSE_ARR)”时,它不是JSON格式。 – https://stackoverflow.com/a/38680699/3419541

从同一个SO页面:

你需要在iOS应用程序中进行debugging。 首先将数据转换为string并打印并检查。 如果string看起来不错,然后打印数据本身 – 有时人们设法添加0字节或控制字符,或者两个字节顺序标记或类似的string中不可见,但不是合法的JSON。 – https://stackoverflow.com/a/38681179/3419541

我已经能够使用以下Git为Spotify创build令牌刷新服务:

https://github.com/adamontherun/SpotifyTokenRefresh

所有你需要做的就是按照git项目中的Heroku链接的指示。

在这里输入图像说明

我试图与项目的作者联系,但他不能告诉我,为什么我的方法不工作,但他的。 所有我可以离开你是这个工作Deploy to Heroku链接。