Need help configuring Django Rest API with Google Oauth and Android

你离开我真会死。 提交于 2021-01-24 07:14:19

问题


I'm trying to configure my django rest API to authenticate using google sign in OAuth and django-rest-framework-social-oauth2

I've already seen this question but I can't seem to figure out how they retrieved the access_token

What I have tried this far following this guide:

Started a new project in console.developers.google.com

Added to settings.py:

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '2377[...].apps.googleusercontent.com'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '[...]'
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = ['email']

INSTALLED_APPS = [
    ...
    # oauth
    'oauth2_provider',
    'social_django',
    'rest_framework_social_oauth2'
]

AUTHENTICATION_BACKENDS = (
    # Google OAuth2
    'social_core.backends.google.GoogleOAuth2',

    # django-rest-framework-social-oauth2
    'rest_framework_social_oauth2.backends.DjangoOAuth2',

    # Django
    'django.contrib.auth.backends.ModelBackend',
)

But when I try to exchange my Auth Code, which I got from Google Sign In on Android

gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestServerAuthCode(Values.CLIENT_ID_WEB_APP)
            .requestEmail()
            .build();

for an access token in my Django Rest API backend using

OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormEncodingBuilder()
    .add("grant_type", "convert_token")
    .add("client_id", Values.CLIENT_ID_REST_APP)
    .add("client_secret", Values.CLIENT_SECRET_REST_APP)
    .add("backend", "google-oauth2")
    .add("token", idToken)
    .build();

I get a 400 HTTP response from server:

{"error":"access_denied","error_description":"Your credentials aren't allowed"}

Am I missing something? Thanks in advance!


回答1:


I got it working once deleted my Application from admin and creating a new one. Also, I deleted all users apart from the admin user.

In my case I have these changes in settings.py file:

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '1234565432-n9vf123456perna7o1oungbqhp6rcl.apps.googleusercontent.com'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '123456trewBNqTL_or38'


SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
]
INSTALLED_APPS = [
    ...
    # Social auth
    'oauth2_provider',
    'social_django',
    'rest_framework_social_oauth2',
]
AUTHENTICATION_BACKENDS = (
    'social_core.backends.google.GoogleOAuth2',
    'rest_framework_social_oauth2.backends.DjangoOAuth2',
    'django.contrib.auth.backends.ModelBackend',
)

On the Android side I have:

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    val serverClientId = getString(R.string.default_web_client_id)
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(serverClientId)
            .requestServerAuthCode(serverClientId)
            .requestEmail()
            .build()


    googleSignInClient = GoogleSignIn.getClient(this, so)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            try {
                val account = task.getResult(ApiException::class.java)
                account?.let {
                    firebaseAuthWithGoogle(it)
                }
            } catch (e: ApiException) {
                Log.w(TAG, "Google sign in failed", e)
            }
        }
    }
private fun firebaseAuthWithGoogle(account: GoogleSignInAccount) {
        val credential = GoogleAuthProvider.getCredential(account.idToken, null)
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    val user = mAuth.currentUser
                    Toast.makeText(this, "Authentication Success.", Toast.LENGTH_SHORT).show()
                    getGoogleAccessToken(account.idToken, account.serverAuthCode)
                } else {
                    Toast.makeText(this, "Authentication Failed.", Toast.LENGTH_SHORT).show()
                }
            }
    }

getGoogleAccessToken is Retrofit API call for the google access token to https://www.googleapis.com/oauth2/v4/token/ URL.

val call = apiInterface?.getAccessToken(
            id_token = tokenId,
            authCode = authCode,
            response_type = "Code",
            redirect_uri = "",
            grant_type = "authorization_code",
            client_id = getString(R.string.default_web_client_id),
            client_secret = getString(R.string.server_client_secret)
        )

The response for the API is with the access token.

data class GoogleSignInAccessTokenDataClass(
val access_token: String,
val expires_in: Int,
val id_token: String,
val token_type: String
)


来源:https://stackoverflow.com/questions/61995469/need-help-configuring-django-rest-api-with-google-oauth-and-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!