Wednesday, 22 June 2016

Authentication with Social Medias in Django

Now no one waste the too much  for registration on a website , they need a flexible authentication  most popular is social-media( Facebook , Google Plus and twitter ).I needed to add Social media authentication to a Django app today, and instead of writing it directly against the Social Media API .I decided to look around and see if there’s a pre-packaged solution for this common task. Turns out, there’s an excellent project called Python Social Auth, and it covers pretty much any social website with an authentication API.. In this Blog, we will use Facebook, Twitter and Google, as the most common social APIs, but we could easily substitute them with LinkedIn, Yahoo  or a bunch of other providers supported by Python Social Auth library.
Django Version : 1.7.4

Step 1 :  Create a project 

         Here am create a project  called  SocialAuth

project in Tree Structre
         SocialAuth/
              manage.py
             SocialAuth/
                __init__.py
                 settings.py
                urls.py
                uwsgi.py
step 2 : Now, the very small customization's we’ll add are

Add ‘SocialAuth’ to INSTALLED_APPS
Create the template for the home page
Add a view for the home page
Add a URL pointing to the home page view

Relevant portion of settings.py:

INSTALLED_APPS = (

    'django.contrib.admin',

    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'SocialAuth',
)

set the static and template root and url in settings.py [ Reffer django Documentaion]

step 3 : Create a folder called templates

    Template: SocialAuth/templates/base.html:


 <!DOCTYPE html>

<html lang="en">
 <head>
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>{% block title %}Social Media Authentication Tutorial{% endblock %}</title>

   <!-- Bootstrap -->
   <link href="/static/css/bootstrap.min.css" rel="stylesheet">
   <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
   <link href="/static/css/fbposter.css" rel="stylesheet">
 </head>
 <body>
   {% block main %}{% endblock %}
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
   <script src="/static/js/bootstrap.min.js"></script>
 </body>
 </html>

Template: SocialAuth/templates/index.html:

{% extends 'base.html' %}

{% block main %}
 <div>
 <h1>Social Media authentication demo</h1>

 <p>
   <ul>
   {% if user and not user.is_anonymous %}
     <li>
       <a>Hello {{ user.get_full_name|default:user.username }}!</a>
     </li>
     <li>
       <a href="{% url 'auth:logout' %}?next={{ request.path }}">Logout</a>
     </li>
   {% else %}
     <li>
       <a href="{% url 'social:begin' 'facebook' %}?next={{ request.path }}">Login with Facebook</a>
     </li>
     <li>
       <a href="{% url 'social:begin' 'google-oauth2' %}?next={{ request.path }}">Login with Google</a>
     </li>
     <li>
     <li>
       <a href="{% url 'social:begin' 'twitter' %}?next={{ request.path }}">Login with Twitter</a>
     </li>
   {% endif %}
   </ul>
 </p>
 </div>
{% endblock %}

step 4 : Create Views.py  inside your SocialAuth project directory

SocialAuth/Views.py

from django.shortcuts import render_to_response

from django.template.context import RequestContext


def home(request):
   context = RequestContext(request,'request': request,'user': request.user})
   return render_to_response('index.html',context_instance=context)


step 5 : Create a file called urls.py

 SocialAuth/urls.py 

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   url(r'^$', 'SocialAuth.views.home', name='home'),
   url(r'^admin/', include(admin.site.urls)),
)

step 6 : Install  Python Scoial Auth

            pip install python-social-auth

step 7 :  Second, let’s make some modifications to our settings.py to include python-social-auth in our project:

     INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'thirdauth',
    'social.apps.django_app.default',
    )

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
    'django.template.loaders.eggs.Loader',
)

AUTHENTICATION_BACKENDS = (
   'social.backends.facebook.FacebookOAuth2',
   'social.backends.google.GoogleOAuth2',
   'social.backends.twitter.TwitterOAuth',
   'django.contrib.auth.backends.ModelBackend',
)

TEMPLATE_CONTEXT_PROCESSORS = (
   'django.contrib.auth.context_processors.auth',
   'django.core.context_processors.debug',
   'django.core.context_processors.i18n',
   'django.core.context_processors.media',
   'django.core.context_processors.static',
   'django.core.context_processors.tz',
   'django.contrib.messages.context_processors.messages',
   'social.apps.django_app.context_processors.backends',
   'social.apps.django_app.context_processors.login_redirect',
)

LOGIN_REDIRECT_URL = ' / ' ( root )


step 8 : Let’s update the urls module to include the new group of URLs : 

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   url(r'^$', 'thirdauth.views.home', name='home'),
   url(r'^admin/', include(admin.site.urls)),
   url('', include('social.apps.django_app.urls', namespace='social')),
   url('', include('django.contrib.auth.urls', namespace='auth')),(  add urls for looging in and looging out.)
)

step 8 : python manage.py migrate and run our project ( python manage.py runserver )

And then start adding API-specific parameters for social networks. Right this moment, if you click on any of the“login with X” links, you’ll get redirected to the corresponding social site, but will get an error about invalid client ID. That’s because we have not provided any client IDs yet.

Facebook

Go to https://developers.facebook.com/apps/?action=create and click the green “Create New App” button.
In the settings of the newly-created application, click “Add Platform”. From the options provided, choose Web, and fill in the URL of the site (http://127.0.0.1:8000/in our example).
Copy the App ID and App Secret, and place them into settings.py file:
SOCIAL_AUTH_FACEBOOK_KEY = …
SOCIAL_AUTH_FACEBOOK_SECRET = …
This should be enough to get your app to login with Facebook! Try logging in and out – you should get redirected between your app and FB OAuth2 service, and a new record in the User social auths table will get created, along with a new User record pointing to it.
Twitter 

Go to https://apps.twitter.com/app/new and create the new application
The callback URL should be something like http://127.0.0.1:8000/complete/twitter/
Copy the values into settings.py:
SOCIAL_AUTH_TWITTER_KEY = …
SOCIAL_AUTH_TWITTER_SECRET = …

Google 

Go to https://console.developers.google.com/ and create a new application.
Under APIs and Auth > Credentials, create a new Client ID.
Make sure to specify the right callback URL: http://127.0.0.1:8000/complete/google-oauth2/
Copy the values into settings file:
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = …
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = …

Conclusion

Python Social Auth can provide more than just authentication. 

Wednesday, 1 June 2016

Static variables and methods in Python

How to declare a data member or a method static in Python? Static means, that the member is on a class level rather on the instance level. Static variables exist only in single instance per class and are not instantiated. If a static variable is changed in one instance of the class, the change will affect its value in all other instances.

Static methods don’t refer to any instance of the class and can be called outside of it. They also cannot access any non-static data members of the class for obvious reasons. Let’s have a look how to get some static from Python.

Variables

All variables defined on the class level in Python are considered static. See this example:

class Example:
    staticVariable = 5 # Access through class

print Example.staticVariable # prints 5

# Access through an instance
instance = Example()
print instance.staticVariable # still 5

# Change within an instance
instance.staticVariable = 6
print instance.staticVariable # 6
print Example.staticVariable # 5

# Change through
class Example.staticVariable = 7
print instance.staticVariable # still 6
print Example.staticVariable # now 7
Seems pretty straight-forward to me. Only confusion might come from the fact, that you can have two different variables in your class under the same name (one static and one ordinary). But I recommend (for your own sakes) to avoid that behavior entirely.

Methods

With static methods it gets a little more complex. In Python, there are two ways of defining static methods within a class.

@staticmethod

Method decorated with this decorator shares with the class only the namespace. Note that, no arguments are mandatory in the method definition. Static method can access classes static variables. See in the following example:

class Example:
    name = "Example"

    @staticmethod
    def static():
        print "%s static() called" % Example.name

class Offspring1(Example):
    name = "Offspring1"

class Offspring2(Example):
    name = "Offspring2"

    @staticmethod
    def static():
        print "%s static() called" % Offspring2.name

Example.static() # prints Example
Offspring1.static() # prints Example
Offspring2.static() # prints Offspring2

@classmethod

The difference between class method and static method in Python is, that class method recieves one mandatory argument – a class name it was called from. Let’s have a look:

class Example:
    name = "Example"

    @classmethod
    def static(cls):
        print "%s static() called" % cls.name

class Offspring1(Example):
    name = "Offspring1"
    pass

class Offspring2(Example):
    name = "Offspring2"

    @classmethod
    def static(cls):
        print "%s static() called" % cls.name

Example.static()    # prints Example
Offspring1.static() # prints Offspring1
Offspring2.static() # prints Offspring2 

Which one should you use? The first option allows you only to access the static variables in the same class. With the second approach you’ll be able to modify class variables of the subclasses without the neccessity of redefining the method when using inheritance. I prefer the first variant, because I personaly think it’s a cleaner solution, but the second variant might come useful in certain situations as well

Private, protected and public in Python


A lot of folks learn object-oriented programming with languages like C++ and Java. And while they learn, they’re told repeatedly (over and over again), that encapsulation is one of the key principles of object-oriented paradigm and that they should take advantage of it. Sure, until you get down with Python :-).

In C++ and Java, things are pretty straight-forward. There are 3 magical and easy to remember access modifiers, that will do the job (public, protected and private). But there’s no such a thing in Python. That might be a little confusing at first, but it’s possible too. We’ll have look at how do it right in Python.

Python doesn’t have any mechanisms, that would effectively restrict you from accessing a variable or calling a member method. All of this is a matter of culture and convention.

Public

All member variables and methods are public by default in Python. So when you want to make your member public, you just do nothing. See the example below:

class Cup:
    def __init__(self):
        self.color = None
        self.content = None

    def fill(self, beverage):
        self.content = beverage

    def empty(self):
        self.content = None
We have there a class Cup. And here’s what we can do with it:

redCup = Cup()
redCup.color = "red"
redCup.content = "tea"
redCup.empty()
redCup.fill("coffee")
All of this is good and acceptable, because all the attributes and methods are public.

Protected

Protected member is (in C++ and Java) accessible only from within the class and it’s subclasses. How to accomplish this in Python? The answer is – by convention. By prefixing the name of your member with a single underscore, you’re telling others “don’t touch this, unless you’re a subclass”. See the example below:

class Cup:
    def __init__(self):
        self.color = None
        self._content = None # protected variable

    def fill(self, beverage):
        self._content = beverage

    def empty(self):
        self._content = None
Same example as before, but the content of the cup is now protected. This changes virtually nothing, you’ll still be able to access the variable from outside the class, only if you see something like this:

cup = Cup()
cup._content = "tea"
you explain politely to the person responsible for this, that the variable is protected and he should not access it or even worse, change it from outside the class.

Private

By declaring your data member private you mean, that nobody should be able to access it from outside the class, i.e. strong you can’t touch this policy. Python supports a technique called name mangling. This feature turns every member name prefixed with at least two underscores and suffixed with at most one underscore into _<className><memberName> . So how to make your member private? Let’s have a look at the example below:

class Cup:
    def __init__(self, color):
        self._color = color    # protected variable
        self.__content = None  # private variable

    def fill(self, beverage):
        self.__content = beverage

    def empty(self):
        self.__content = None

Our cup now can be only filled and poured out by using fill() and empty() methods. Note, that if you try accessing __content from outside, you’ll get an error. But you can still stumble upon something like this:

redCup = Cup("red")
redCup._Cup__content = "tea"