OAuth2.0 при использовании API аутентификации YouTube v3 Неверные учетные данные - PullRequest
0 голосов
/ 21 октября 2019

Я потратил несколько дней на то, как реализовать «простой» вход в Google через консоль API Google и API Firebase. Поскольку у меня нет сервера, я хотел бы иметь доступ к учетной записи пользователя, только когда он использует приложение. Моя цель - получить идентификаторы каналов пользователя, чтобы я мог загрузить все его загруженные видео.

Для этого я создал новый проект в API консоли Google, связал его с Firebase и использовал его. учебник ссылка , чтобы интегрировать его в мое приложение. Я дошел до того, что пользователь может выбрать учетную запись Gmail и войти в систему, приложение также запрашивает ряд разрешений YouTube, которые пользователь должен разрешить. После этого я получаю accountUid пользователя (тот, который показан в консоли Firebase).

С этого момента я запутался, потому что в некоторых руководствах упоминался доступ к токену, токены обновления, идентификатор клиента, секрет клиента, которого у меня нет, и не уверен, нужны ли эти учетные данные для моего приложения.

После успешного входа в систему я использую этот вызов API для получения его каналов своей учетной записи YouTube:

 @GET("channels")
    fun getChannelsList(@Query("part") part :String = "contentDetails,snippet",@Query("mine") mine : Boolean = true, @Header("Authorization") accessToken : String) : Single<ChannelResponse>

Но я получаю эту ошибку:

{
  "error": {
  "errors": [
  {
     "domain": "global",
     "reason": "authError",
     "message": "Invalid Credentials",
     "locationType": "header",
     "location": "Authorization"
  }
  ],
  "code": 401,
  "message": "Invalid Credentials"
}
}

из этой ссылки Я также попытался поместить "Bearer" как часть значения заголовка с тем же результатом.

Я также попробовал googleSignInAccount.idToken, но это тоже не помогло.

Это код моего LoginActivity:

class LoginActivity : BaseActivity(), View.OnClickListener,OnCompleteListener<AuthResult>{

    var idTokenString = ""
    val TAG = "LoginActivity"
    val mAuth = FirebaseAuth.getInstance()
    private var mAuthListener: FirebaseAuth.AuthStateListener? = null
    var googleAccount : GoogleSignInAccount?=null

    override fun layoutRes(): Int {
        return app.globe.com.youtubeplaylist.R.layout.activity_login
    }

    override fun initUI() {
        login.setOnClickListener(this)
        logout.setOnClickListener(this)
    }



    companion object {
        const val RC_SIGN_IN = 1000
    }

    private var googleSignInClient : GoogleSignInClient?=null

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


        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(app.globe.com.youtubeplaylist.R.string.default_web_client_id))
            .requestEmail()
            .requestScopes(Scope("https://www.googleapis.com/auth/youtube.readonly"),
                           Scope("https://www.googleapis.com/auth/youtube.force-ssl"))
            .build()


        googleSignInClient = GoogleSignIn.getClient(this,gso)
        googleSignInClient!!.signInIntent

    }

    override fun onStart() {
        super.onStart()
        val currentUser = mAuth.currentUser
        checkAccount(currentUser)
    }

    override fun onClick(v: View) {
        when (v.id) {
            app.globe.com.youtubeplaylist.R.id.login -> {
                signIn()
            }
            app.globe.com.youtubeplaylist.R.id.logout ->{
                signOut()
            }
        }
    }

    private fun signOut()
    {
        FirebaseAuth.getInstance().signOut()
        checkAccount(null)
    }

    private fun signIn() {
        val signInIntent = googleSignInClient!!.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)
    }



    public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            // The Task returned from this call is always completed, no need to attach
            // a listener.
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            try {
                // Google Sign In was successful, authenticate with Firebase
                googleAccount = task.getResult(ApiException::class.java)
                firebaseAuthWithGoogle(googleAccount!!)
            } catch (e: ApiException) {
                // Google Sign In failed, update UI appropriately
                Log.w(TAG, "Google sign in failed", e)
                // ...
            }

        }
    }

    private fun firebaseAuthWithGoogle(acct : GoogleSignInAccount)
    {
        Log.d(TAG, "firebaseAuthWithGoogle:" + acct.id)

        val credential = GoogleAuthProvider.getCredential(acct.idToken, null)



    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, this)

    }



    override fun onComplete(task: Task<AuthResult>) {

        if (task.isSuccessful) {
            // Sign in success, update UI with the signed-in user's information
            Log.d(TAG, "signInWithCredential:success")
            var user = mAuth.currentUser
            checkAccount(user)
        } else {
            // If sign in fails, display a message to the user.
            Log.w(TAG, "signInWithCredential:failure", task.exception)
            Snackbar.make(main_layout, "Authentication Failed.", Snackbar.LENGTH_SHORT).show()
            checkAccount(null)
        }

    }


    private fun checkAccount(account : FirebaseUser?)
    {
        if(account!=null)
        {
            val mainIntent = Intent(this,MainActivity::class.java)
            startActivity(mainIntent)
        }
        else
        {
            login.visibility = View.VISIBLE
            logout.visibility = View.GONE
        }
    }    
}

Спасибо!

1 Ответ

0 голосов
/ 29 октября 2019

Это default_web_client_id может быть неправильным.

Каким бы ни было app.globe.com.youtubeplaylist.R.string.default_web_client_id.

см. GoogleSignInOptions.Builder . requestIdToken (String serverClientId):

Указывает, что запрашивается токен идентификатора для аутентифицированных пользователей.

Для запроса токена идентификатора необходимо указать идентификатор клиента сервера.

serverClientId Идентификатор клиента сервера, которыйпроверит целостность токена.


Перейдите console.firebase.google.com , выберите проект, затем нажмите

Authentication> Sign-In method> Google> Web SDK configuration.

Там вы найдете «Идентификатор веб-клиента» и «Секрет веб-клиента» для использования.

Также в Google Cloud Учетные данные API страница, как «Идентификатор клиента для веб-приложения».


Область https://www.googleapis.com/auth/youtube.force-ssl может потребовать область https://www.googleapis.com/auth/youtube (обе они предназначены для управления учетной записью YouTube). Для просмотра контента достаточно объема https://www.googleapis.com/auth/youtube.readonly.

...