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

时间:2016-11-26 00:53:13

标签: ios swift spotify

  

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)

现在用户无法再登录了,我收到了错误。如果我要删除tokenSwapURLtokenRefreshURL,则所有内容都会重复,但用户必须每60分钟重新验证一次。

如果我尝试使用已登录的用户刷新令牌,我会收到:

  

"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
            }
        })
}

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

2 个答案:

答案 0 :(得分:2)

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

  

https://github.com/adamontherun/SpotifyTokenRefresh

您需要做的就是遵循git项目中Heroku链接的说明。

enter image description here

我曾尝试与该项目的作者取得联系,但他无法告诉我,为什么我的方法不起作用,但他的方法是。我可以留下的就是这个有效的Deploy to Heroku链接。

答案 1 :(得分:1)

简短摘要:假设您的JSON解析正常,问题是JSON(服务器端)格式不正确。

  

JSON文本不是以数组或对象开头,而是选项允许未设置片段

可以通过返回

JSONSerialization.jsonObject(with:options:)抛出
  

来自data

中的JSON数据的Foundation对象      

nil 如果发生错误

格式错误的JSON»nil而不是令牌»当前令牌会被填充»结果:“用户无法再登录”

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

  

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

来自同一个SO页面:

  

您需要在iOS应用程序中对此进行调试。首先将数据转换为字符串并打印并检查它。如果字符串看起来不错,那么打印数据本身 - 有时人们设法添加0字节或控制字符,或两个字节顺序标记或类似的东西在字符串中不可见但不是合法的JSON。 - https://stackoverflow.com/a/38681179/3419541