我正在使用JetBrains Compose和Ktor构建我的第一个桌面应用程序。我想使用Spotify Auth PCKE extension连接到Spotify API。流程应该是
1.向accounts. spotify. com/authorize发送获取身份验证请求
1.如果用户未授权-〉启动网页供用户登录
- Spotify向初始请求中提供的URL发送回调。
1.从Spotify接收代币
我在启动用户登录网页并在我提供的URL上获得响应时遇到了问题。我使用桌面的默认浏览器启动网页,并打开了一个应该监听"http://localhost:8888/callback)"的websocket。我注意到,当我与启动的网页交互时,URL显示Spotify返回的响应("http://localhost:8888/callback?error=access_denied&state=initial"),但我的websocket代码从未被调用。这是我启动浏览器或websocket的方式的问题...还是我在总体上做错了?
class SpotifyClient {
private val client: HttpClient = HttpClient(CIO) {
followRedirects = true
install(WebSockets) {
contentConverter = KotlinxWebsocketSerializationConverter(Json)
}
handleSpotifyAccountAuthResponse()
}
private val clientId = "<Removed for Post>"
suspend fun authorizeSpotifyClient(): HttpResponse {
val withContext = withContext(Dispatchers.IO) {
val response: HttpResponse =
client.get(NetworkConstants.BASE_URL_SPOTIFY_ACCOUNTS + NetworkConstants.PATH_SPOTIFY_AUTH) {
header("Location", NetworkConstants.BASE_URL_SPOTIFY_AUTH_REDIRECT_URI)
parameter("client_id", clientId)
parameter("response_type", "code")
parameter("redirect_uri", NetworkConstants.BASE_URL_SPOTIFY_AUTH_REDIRECT_URI)
parameter("state", ClientStates.INITIAL.value)
parameter("show_dialog", false)
parameter("code_challenge_method", PCKE_CODE_CHALLENGE_METHOD)
parameter("code_challenge", generatePCKECodeChallenge())
parameter(
"scope",
NetworkUtils.getSpotifyScopes(
ImmutableList.of(
SpotifyScopes.USER_READ_PLAYBACK_STATE,
SpotifyScopes.USER_READ_CURRENTLY_PLAYING
)
)
)
}
println("Auth Spotify API Response $response")
println("Auth Spotify API Response Code ${response.status}")
client.close()
return@withContext response
}
accountAuthRedirectWebsocket()
return withContext
}
private fun HttpClientConfig<CIOEngineConfig>.handleSpotifyAccountAuthResponse() {
HttpResponseValidator {
validateResponse { response ->
handleValidAccountResponse(response)
}
handleResponseExceptionWithRequest { exception, request ->
}
}
}
private fun handleValidAccountResponse(response: HttpResponse) {
if (response.status.value == 200) { // success
val responseUrl = response.call.request.url
if (responseUrl.toString().contains("continue")) {
println("Needs a redirect, ${responseUrl.toString()}")
openWebpage(responseUrl.toURI())
}
}
}
private fun openWebpage(uri: URI?): Boolean {
val desktop = if (Desktop.isDesktopSupported()) Desktop.getDesktop() else null
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
try {
desktop.browse(uri)
return true
} catch (e: Exception) {
e.printStackTrace()
}
}
return false
}
private suspend fun accountAuthRedirectWebsocket(){
client.webSocket(method = HttpMethod.Get, host = "localhost", port = 8888, path = "/customer/1") {
println("Got a response in the socket")
}
}
1条答案
按热度按时间des4xlb01#
为了接收回调,我需要实现一个如下所示的本地服务器。在这种情况下,使用WebSocket是错误的方法,并且没有提供我所期望的功能。