Custom User model for Django with Facebook Login - django

On the client side I use the iOS SDK for Facebook to login and I get the Facebook ID and the access token.
Now on the Django side of things I would like to create a user with Facebook ID as the primary identifier and other fields like access token, first name, last name etc (the last two of which I will retrieve from the Graph API on the server side).
I know that I have to create a custom user model.
If you wish to store information related to User, you can use a one-to-one relationship to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.
This will not be enough as I will be using the Facebook ID and the access token for authentication.
This leaves me with two options: I can substitute a custom user model like so:
AUTH_USER_MODEL = 'myapp.MyUser'
Or I can subclass AbstractUser:
If you’re entirely happy with Django’s User model and you just want to
add some additional profile information, you can simply subclass
django.contrib.auth.models.AbstractUser and add your custom profile
fields.
But that doesn't sound quite right either. Also this design tip has confused me a little more.
Model design considerations
Think carefully before handling information not directly related to authentication in your custom User Model.It may be better to store app-specific user information in a model that has a relation with the User model.
What is the best way to implement what I am trying to do?

Just a side note: The problem of a custom user is that it is often the case that other apps (and yes, you will use them) don't interact correctly with it due to the assumptions they make on the base model for auth.
This will not be enough as I will be using the Facebook ID and the access token for authentication.
I'm not sure you really need a custom user. For instance, I'm using open id for authentication and there is no problem in using the default user: there is just another model with a OneToOne relationship to the default user.
The main concern you should have for a Facebook ID for authentication (and authentication in general) is to have a custom authentication Backend with its own specific facebook authentication.
Internally, authenticate() runs through all installed backends (settings.AUTHENTICATION_BACKENDS) and tries to authenticate the user with one of those.
You can search some of the existing implementations e.g. in Django packages for facebook authentication.

If your users should be enabled to login/register with username, mail and password -> use a OneToOne relationship to django's usermodel to store facebook credentials.
If your usermodel entirely depends on facebook data and you don't want your users to login with username/pass -> substitute the usermodel with AUTH_USER_MODEL = 'myapp.MyUser'.
You might also want to take a look at django-allauth which solves much of your problems in a sweet little package.

Related

Session ID tokens in django without auth.models.User

I know that one can set up authentication with the built in django login(request, user), request.is_authenticated when the user acquires the sessionid cookie, and authenticate(request, username="foo", password="bar").
However, underneath this interface, django creates a User object in the database. I am authenticating using other means, namely LDAP. I can opt for just passing the username and password for LDAP every single time, but having a sessionid token would be ideal.
Is there any way to use the same login(), request.is_authenticated, authenticate() API but without using the User model underneath? Another alternative is fine as well. The one restriction that I have is that I do not want to use another library.
Thanks!
As far as I know, its not possible to use djangos authentication/autorization framework without the User model.
In the part where the docs talk about customizing authentication, it is always centered around the User model (even if it is your custom user model).
That being said, you could look into something really hackish: creating your custom user model that is not stored in the database.
For that you'll probably need custom fields and managers that prevent database calls while still making certain fields available in the model (like email and username). I never tried it, but it should be possible by overriding djangos default behavior in the right places.
But all that effort is probably not worth the trouble. Just write your own authentication backend that automatically creates an User instance on successful authentication against your LDAP source, so you can "harness the full potential of the django User model".

Integration of django authentication system with Facebook API

I am integrating Django authentication and login system with Facebook Login API. The problem is that once Facebook username will be the same as existing in my project's database so the only solution to the problem is to catch Facebook username and add numbers or something to the string to make it unique ? Is it correct ? How is it normally handled ?
You have several options, I'm sure I won't think of them all.
If you have an unique constraint on the field for 'username', you can add numbers to remain unique.
Remove the unique constraint on the 'username' field. Add a boolean to the user table, to identify users logging in with facebook. You are probably able to determine when a user logins with a facebook account. After logging in you can crossmatch the information with the user you have in the database. Facebook probably has some kind of 'unique' data about a specific user which you can place in your database to differentiate between unique users with the same name.

Multiple User Types For Auth in Django

My web features two user types, Client and Professional. There are also two 'main modules', one for clients to buy stuff and so on (the main site), and the other for professionals to manage operations. For auth, I would like to have:
A single 'sign in' form, which detects whether the user is a client or a professional and forwards her to the right module (main site or management site).
Two 'sign up' forms, one for clients and other for professionals. Probably, the site will ask the user whether she wants to register as a professional or as a client, to trigger the right registration flow for each case.
Clients will use the 'main site' and should not be authorized to use the 'management site'.
Professionals will use the 'management site' but should not be authorized to sign in to the main site.
Both professionals and clients are registered as Users, and share common fields, such as username, phone, email, etc...
Since Django won't let me use two models for authentication. I've created custom model subclassing AbstractBaseUser and which serves me as a base auth class for Client and Professional.
class BaseUser(AbstractBaseUser):
...
class Client(BaseUser):
...
class Professional(BaseUser):
...
I've also changed the AUTH_USER_MODEL setting to:
AUTH_USER_MODEL = 'myapp.BaseUser'
I've also included django-allauth to manage user registration and authentication. But now I'm stuck. I just began playing with Django/Python and I'm not sure how to solve this.
It seems there is no official recommended way for doing this (Implementing multiple user types with Django 1.5). Should I stick to the subclassing approach, or should I do the OnetoOne relationship pointed out in the docs ?
Once I have the models properly setup, how should I proceed with the two registration forms? Is it possible to accomplish this with django-allauth, or do I need to do it manually?
As far as I know, when a new user is registered, a new base user is created in the User table. But since I will be creating user specializations (Client or Professional), how should I specify that I also want to create the client-related data or professional-related data in the corresponding table?
I'm pretty new to Django, so any advise will help
I think the easiest way for you to do what you are talking about is going to be to have 3 apps in your project: your top level app, a "professional" app and a "client" app. At the top level app, all you really need to do is give the users a login form, and 2 links, one for registering as a Professional and one for registering as a Client.
In this case, I believe it will be easiest for you to use Django's built in Permissions system, and assign each type of user to a corresponding group (eg. professionals and clients). You can use a decorator on your views to ensure that only members of a particular group can access that view (since you have 2 separate apps for each group, you can add a decorator to all views in each of them, or you can import Django's authorization functions into your urls.py and check it there, although that is beyond the scope of this answer).
Registration is easy enough, use your urls.py file to forward the user that wants to register to the correct app. Once you do that, you should be able to use django-allauth registration on each app, allowing you to create 2 different kinds of users. Make sure when the register, you assign them to the correct group membership.
As for the login redirection, once you receive the POST data, I would check for which type of user logged in, and use that to forward the user to the correct URL that goes with the Professional or Client app. You can see the below link for an idea of redirecting a user after login.
Django - after login, redirect user to his custom page --> mysite.com/username

django user authentication, shoulid admin be used or created from view?

I am completely new to Django. I have done all the tutorials and would now like to create a simple user authentication to be able to access a page in my site.
My question is as to whether I should use the admin authentication? Or should I create my own customer view with a user name and password and use the DJango authentication api?
To clarify, I have a page that I want secured and to only be view when a user has permission to view it. Is this a reasonable thing to do in the built in Django admin? It seems the Django admin is for giving permission to create new records related to an apps model.
Thanks!
I would prefer using Django's built in authentication system. Lets assume that you'd want to create you own customer model with say mobile number and twitter handle, you can extend Django's User model by following
from django.contrib.auth.models import User
class Customer(User):
mobile = models.CharField(max_length=12)
twitter = models.CharField(max_length=100)
In this case not only would you inherit attributes like email, username etc from Django's User model but you'll also add you custom attributes that you can store in database.
The easiest approach to securing your pages would be to use login_required decorator. Also take care of including right URLs while securing your pages to make sure you have included Django's login and logout URLs

Django - Cannot login when subclassing User model

I searched for a similar question but found none so far.
I have a subclass of User (django.contrib.auth.models.User). I want my site to support both Individual users and Business users, so in this case it's:
class BusinessUser(User):
website = models.CharField(max_length=20)
objects = UserManager()
I have a register form that saves a user as a User and another one that saves my user as a BusinessUser. The problematic case is the BusinessUser:
I have checked through the Django console that both an User and a BusinessUser object exists after registration of a BusinessUser, and all fields are fine (username, email, password).
However, on my login page, I cannot login with my BusinessUser's. I can login fine with the normal User's registered, but not BusinessUser's.
Does anyone know what might be wrong?
Thank you.
Custom authentification backend should be used when django's User subclassed
You can see example here
I haven't tested this, but I believe this will work.
You subclassed User. Don't do that ever. Use profiles to add additional data, and if you really need two separate models (say for having two separate views for individual and business users in the admin) create proxy models and custom managers that filter only individual or business users from User.