Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need help configuring Django Rest API with Google Oauth and Android

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!

like image 203
Ezequiel Gimenez Avatar asked Dec 02 '25 10:12

Ezequiel Gimenez


1 Answers

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
)
like image 121
Rana Ranvijay Singh Avatar answered Dec 03 '25 23:12

Rana Ranvijay Singh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!