I was trying set up google authentication with react frontend and django rest framework backend. I set up both the frontend and backend using this two part tutorial, PART1 & PART2. When I try to login with google in the frontend I get POST http://127.0.0.1:8000/google-login/ 400 (Bad Request) I think it's because my google api needs an access token and an authorization code to be passed. After debugging the react js, I noticed the response I get from google doesn't have an authorization code. I suspect because responseType is permission(by default), Source:React login props , instead of code. I was wondering how would you change the response type in react? (I'm not even sure if this alone is the issue)
Here's my backend code
In my views.py file
class GoogleLogin(SocialLoginView):
adapter_class = GoogleOAuth2Adapter
callback_url = "http://localhost:3000"
client_class = OAuth2Client
in my urls.py
path('google-login/', GoogleLogin.as_view(), name='google-login'),
for my front end
/Components/login.js
const googleLogin = async (accesstoken,code) => {
console.log(accesstoken)
let res = await cacaDB.post(
`google-login/`,
{
access_token: accesstoken,
code: code
}
);
console.log(res);
return await res.status;
};
const responseGoogle = (response) => {
console.log(response.code);
googleLogin(response.accessToken, response.code);
}
return(
<div className="App">
<h1>LOGIN WITH GOOGLE</h1>
<GoogleLogin
clientId="client_id"
buttonText="LOGIN WITH GOOGLE"
onSuccess={responseGoogle}
onFailure={responseGoogle}
/>
</div>
)
I want to save the user in the database and have them stay logged in, in the front end.
This Post explains the login flow behind the scene. Here's Login flow image I'm basically stuck on returning code and accesstoken(I can return this successfully) step.
Here's my list of questions,
class GoogleLogin(SocialLoginView), take care of the steps of validating the access token and code with google and creating the user with that email in database?Would really appreciate your inputs.
After investigating a bit on my end, I think I might have a solution that works for you.
I've messed with OAuth before, and it's quite tricky sometimes because it has to be robust. So a bunch of security policies usually get in the way.
I'll provide my full step-by-step, since I was able to get it working, trying my best to match what you posted.
Firstly, to have a clean slate, I went off the example code linked in the tutorials. I cloned and built the project, and did the following:
http://localhost:3000 to the "Authorized JavaScript origins" and "Authorized redirect URIs" sectionsSite, with value of localhost:8000 for both fields.Social Application with Client ID and Secret Key as the "Client ID" and "Client Secret" from GCP, respectively. I also picked the localhost site that we added earlier and added it to the right hand box. (I left Key blank)Example of my Application Page
clientId field in App.js, in the params of the GoogleLogin component.Here's where I ran into a bit of trouble, but this is good news as I was able to reproduce your error! Looking at the request in the network inspector, I see that for me, no body was passed, which is clearly the direct cause of the error. But looking at App#responseGoogle(response), it clearly should pass a token of some sort, because we see the line googleLogin(response.accessToken).
So what is happening is that accounts.google.com is NOT returning a proper response, so something is happening on their end, and we get an invalid response, but we fail silently because javascript is javascript.
After examining the response that Google gave back, I found this related SO post that allowed me to fix the issue, and interestingly, the solution to it was quite simple: Clear your cache. I'll be honest, I'm not exactly sure why this works, but I suspect it has something to do with the fact that development is on your local machine (localhost/127.0.0.1 difference, perhaps?).
You can also try to access your site via incognito mode, or another browser, which also worked for me.
I have knox token set up, can I use it instead of the JWT tokens?
I don't think I have enough knowledge to properly answer this, but my preliminary research suggests no. AFAIK, you should just store the token that Google gives you, as the token itself is what you'll use to authenticate. It seems that Knox replaces Django's TokenAuthentication, which means that Knox is in charge of generating the token. If you're offloading the login work to Google, I don't see how you could leverage something like Knox. However, I could be very wrong.
Does the
class GoogleLogin(SocialLoginView), take care of the steps of validating the access token and code with google and creating the user with that email in database?
I believe so. After successfully authenticating with Google (and it calls the backend endpoint correctly), it seems to create a "Social Account" model. An example of what it created for me is below. It retrieved all this information (like my name) from Google.
Example of my "Social Accounts" page
As for how to retrieve the login from the browser's local storage, I have no idea. I see no evidence of a cookie, so it must be storing it somewhere else, or you might have to set that up yourself (with React Providers, Services, or even Redux.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With