Firebase Token Authentication using Django - django

I am new to django and am trying to get the user authenticated using firebase admin sdk. I am trying to do token authentication and have setup the admin sdk in my django app. Also I have received the client id token in the android app.
Now I am unable to understand how to send this id to the backend and verify it as a user and create users accordingly.I did find this answer but couldn't really understand how to go about this.
Also if a user is verified how do I add and update its data. Do I pass the token again or is there any other way to do it?

Your Android App should send its ID token along with all requests sent to the backend server. You can decide how to include that (as a header, as part of a JSON payload etc). In the backend server, you should always call auth.verify_id_token() and return an error (e.g. 401 Unauthorized) if the token fails to validate.

Related

How to integrate Facebook Login in django-graphql-jwt?

We have a django project that uses the Graphene-Django library to implement a GraphQL API in our project. This backend is accessed by our mobile apps. For the authentication of the apps, we use the django-graphql-jwt library, which is a JSON Web Token library in Django with GraphQL approach.
Now we want to implement the Facebook Login in our system and with it the authentication happens in Facebook. After authentication, what will be sent to our backend from the mobile app is only the email of the user. How can I register and authenticate the user in django-graphql-jwt without the password? Or is there a better workflow for this?
After authentication, what will be sent to our backend from the mobile app is only the email of the user.
Hey Al Ryan, this seems like a faulty implementation of OAuth, what you get back from facebook is a token you send that token to your server, and it will send it back to facebook to verify it's not faked, then only user can be logged in.
Otherwise anyone can call the server with a email and act as that user.
This is a library with social auth and JWT support, see if this helps.
I'm also sharing solution from my project
Create a facebookAuth named graphql mutation
Above mutation will take two params access_token and access_verifier
Send a GET request to this url f"https://graph.facebook.com/me?fields=name,email&access_token={access_token}"
If json response has a key errors, stop user from logging in.
Otherwise above response will contain email, use it to create/get a User object.
Now you simply need to return the JWT token from your mutate function.
To generate access and refresh tokens call this function jwt_encode, imported as from dj_rest_auth.utils import jwt_encode
above will return tuple access_token, refresh_token
Note I have used dj_rest_auth instead of django-graphql-jwt, but it's pretty equivalent you just need a function to sign the JWT, rest all is custom logic so better write yourself.
PS: OAuth is a sensitive entry-point for attackers so implement is securely, you can contact at atul7555[at]gmail.com for any assistance.

Flutter google sign in authenticate django social auth for google

I am creating a flutter android app which uses google sign in. Once logged in, I recieve accesstoken and idtoken. I want to use this token to authenticate my backend which uses django social auth and
Login and return the authoken, if the user has already signed up, or
Register the user , login and return the user id and authtoken.
Is this possible ? If so please suggest any documents online or please explain how should I approach this.
Over the years of doing this again and again, I found the solution below works well for me. It creates clear understanding of who is doing what.
Basically, you need:
Django Rest framework-backed token authentication for normal API requests. Mostly your app works on this. Link: https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
Google or Facebook or any other login to issue an auth token in 1. Thus effectively FB/ Google shortcuts the process of typing in username and password.
This is achieved via the flow below:
New user comes in and signs in via FB/ Google
You get Fb/Google token and send it to your backend
You verify the validity of the token. Re-obtain user name and email from G/FB from the backend. Use these details to create a user account in your backend. DO NOT USE email provided from front-end for account creation (assuming email is your primary unique user identifier)
NOTE: Don't forget to check if account already exists. If it does, this is a returning user/ login and not a new user. In this case, validate and return valid Django Rest Token
Once 3 is complete, issue a Django REST framework Token in response to the request made in 3.
After 4, you have a token in your app. Use this token for normal requests.
Happy coding! Happy to answer follow-up questions.
it is possible,first you have to create your api using django Rest Framework,the link below can help you to create your backend and set a token for every user:
https://dev.to/amartyadev/flutter-app-authentication-with-django-backend-1-21cp
then you have to add social authentication to your backend,you can write it yourself or using link below to use library :
https://github.com/RealmTeam/django-rest-framework-social-oauth2
after this approach you have to create your flutter app,the below link is a useful resource to connect your backend and your flutter app :
https://www.asapdevelopers.com/flutter-login-app-with-python-backend/

user authentication using async websocket instead of django channels

I have a websocket service previously written using python websocket package which can access django models. Is it possible to check if the messages are coming from an authenticated user without using django channels?
Well, no answers, so you get to watch me at work.
I made an alternative login api rate limited to 3 requests per minute which would return the token if you send it a username and password.
I changed the django login template to include the token query
token query works before username and password is posted to the django server
token is retrieved before login and placed into browser's session storage
user logs in, websocket page is loaded, we've got the token in the session storage
websocket connection is created using the token in the session storage so webscoket server now has the token for authentication
use token for authentication to retrieve the account data on server side and route requests to the websocket object according to that.

Django REST framework - prevent data access for user view?

In my api, I have a /users endpoint which currently shows (eg address) details of all users currently registered. This needs to be accessed by the (Ember) application (eg to view a user shipping address) but for obvious reasons I can't allow anyone to be able to view the data (whether that be via the browsable api or as plain JSON if we restrict a view to just use the JSONRenderer). I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
Am I missing something?
UPDATE
Hi, I wanted to come back on this.
For authentication on the Ember side I'm using Ember Simple Auth and token based authentication in Django. All is working fine - I can log into the Ember app, and have access to the token.
What I need to be able to do is to access the user; for this I followed the code sample here https://github.com/simplabs/ember-simple-auth/blob/master/guides/managing-current-user.md
I have tested the token based authentication in Postman, using the token for my logged in user - and can access the /users endpoint. (This is returning all users - what I want is for only the user for whom I have the token to be returned but that's for later!).
The question is how to do I pass the (token) header in any Ember requests, eg
this.store.findAll('user') .... etc
This is clearly not happening currently, and I'm not sure how to fix this.
UPDATE
Fixed it. Turns out that the authorize function in my application adapter was not setting the headers, so have changed the code to set the headers explicitly:
authorize(xhr) {
let { access_token } = this.get('session.data.authenticated');
if (isPresent(access_token)) {
xhr.setRequestHeader('Authorization', `Token ${access_token}`);
}
},
headers: computed('session.data.authenticated.token', function () {
const headers = {};
if (this.session.isAuthenticated) {
headers['Authorization'] = `Token ${this.session.data.authenticated.token}`
}
return headers;
})
Ember is framework for creating SPAs. These run in the browser. So for Ember to get the data, you have to send the data to the browser.
The browser is completely under the control of the user. The browser is software that works for them, not for the owner of the website.
Any data you send to the browser, the user can access. Full stop.
If you want to limit which bits of the data the user can read from the API, then you need to write the logic to apply those limits server-side and not depend on the client-side Ember code to filter out the bits you don't want the user to see.
I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
This doesn't really make sense.
Generally, this should happen:
The user enters some credentials into the Ember app
The ember app sends them to an authentication endpoint on the server
The server returns a token
The ember app stores the token
The ember app sends the token when it makes the request for data from the API
The server uses the token to determine which data to send back from the API

Can DjangoRestFramework accept JWTs that have more than username/password in payload?

I have a Django application that uses the Django Rest Framework. At first I was just using Session, and Token authentication, but now want to implement JWT Token authentication. I downloaded a package called djangorestframework-jwt that allows you to use JWT for authentication in DRF. The crux of the problem is that my client side application is using Auth0 which can return a lot of different information, first name, last name, userid, etc. We are using Auth0 with gmail as an identity provider to log into our client side EmberJS application. For our data adapters to get data from Django though, we are using 1 consistent token that we configured in our Auth0 account that is tied to a user in Django. What I would like to accomplish is to use the JWT returned from Auth0, instead of this 1 token, to authenticate all our requests to Django. Can you authenticate yourself in Django without using a Django User object?