Home > Net >  POST authorization request to Spotify Api with Retrofit
POST authorization request to Spotify Api with Retrofit

Time:08-30

I am trying to use Spotify API. But as the given auth token expires every hour, so I have to post a request to API to get a new one. I found a code on the official website that shows how to do it.

var client_id = 'CLIENT_ID';
var client_secret = 'CLIENT_SECRET';

var authOptions = {
  url: 'https://accounts.spotify.com/api/token',
  headers: {
    'Authorization': 'Basic '   (new Buffer(client_id   ':'   client_secret).toString('base64'))
  },
  form: {
    grant_type: 'client_credentials'
  },
  json: true
};

request.post(authOptions, function(error, response, body) {
  if (!error && response.statusCode === 200) {
    var token = body.access_token;
  }
});

But I am new to retrofit and I don't know any js. So I don't know how can I convert this code to kotlin. can anyone help me out?

CodePudding user response:

Step 1 :Create interface named ApiInterface.kt.

interface ApiInterface {
    @POST("token")
    fun getToken(): Call<ResponseBody>
}

Step 2 : In your activity paste these functions

public static Retrofit getClient(final String token) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .addInterceptor(new NetInterceptor())
                .addInterceptor(chain -> {
                    Request newRequest = chain.request().newBuilder()
                            .addHeader("Authorization", "Basic "   getBasicAuth(clientId, clientServer))
                            .build();
                    return chain.proceed(newRequest);
                })
                //.followRedirects(false)
                //.followSslRedirects(false)
                .connectTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .build();

        return new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();
    }

convert basic auth to base64

private fun getBasicAuth(client_id: String, client_secret: String): String {
        val data = ("$client_id:$client_secret").toByteArray(StandardCharsets.UTF_8)
        return Base64.encodeToString(data, Base64.DEFAULT)
    }

Step : 3 Do an api call

private fun apiCall() {

        val call = getClient()!!.create(ApiInterface::class.java).getToken()

        call.enqueue(object : Callback<UserResponse> {
            override fun onResponse(call: Call<UserResponse>, response: Response<UserResponse>) {
                Toast.makeText(this@MainActivity, response.code().toString()
                          " "   response.body().toString(), Toast.LENGTH_SHORT).show()
            }

            override fun onFailure(call: Call<UserResponse>, t: Throwable) {
                Toast.makeText(this@MainActivity, t.localizedMessage!!.toString(),
                    Toast.LENGTH_SHORT).show()
            }
        })
    }

Step 4 : call api in your onCreate() method.

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        apiCall()
    }

CodePudding user response:

after many hours of research, i was able to figure out. here is the interface:

    @POST("api/token")
    @FormUrlEncoded
    fun getToken(
        @Header("Authorization") auth: String,
        @Header("Content-Type") content: String,
        @Field(("grant_type")) grantType: String
    ): Call<Token>

here is the activity:

private fun getToken(id:String) {
        val retrofit: Retrofit = Retrofit.Builder().baseUrl(TOKEN_URL)
            .addConverterFactory(GsonConverterFactory.create()).build()
        val service : TopTrackApi = retrofit.create(TopTrackApi::class.java)

        val base64String = "Basic "  get64BaseString("$clientID:$clientSECRET")

        val listCall : Call<Token> = service.getToken(base64String,"application/x-www-form-urlencoded","client_credentials")
        listCall.enqueue(object : Callback<Token> {
            override fun onResponse(response: Response<Token>?, retrofit: Retrofit?) {
                if (response?.body() != null) {
                    setUpRV(id,response.body().access_token)
                }
                if(response?.body() == null){
                    Log.i("Response!", "null response body /getToken")
                }
            }
            override fun onFailure(t: Throwable?) {
                Log.e("Error", t!!.message.toString())
            }
        })

    }

    fun get64BaseString(value:String):String{
        return Base64.encodeToString(value.toByteArray(), Base64.NO_WRAP)
    }
  • Related