1. 程式人生 > >使用Django實現微信公眾號用戶openid登錄認證

使用Django實現微信公眾號用戶openid登錄認證

cor 先生 uri lse 文本消息 利用 AR tps elb

最近在用Django做一個小項目,需要將微信的用戶與網站的用戶進行關聯,由於是微信的訂閱號,沒有oauth網頁授權的權限,只能退而求其次,在響應中獲取用戶的openid,來唯一的標識用戶。

Django中用戶的模型繼承和擴展於AbstractUser,在用戶模型中添加openid字段:
models.py

class Users(AbstractUser):
    openid = models.CharField(max_length=100,blank=True,null=True,verbose_name="openid",unique=True)

我們擴展了用戶的模型,並使用這個模型來作為用戶認證的模型,需要在setting.py文件裏指定認證的模型(website是django應用的名稱,非項目名稱):

AUTH_USER_MODEL = ‘website.Users‘
這樣,我們就能夠使用上面定義的Users模型來進行用戶的登錄和註冊操作了。

一個常見默認的Django登錄認證,使用的是authenticate,在此引用Django文檔中的敘述:

認證一個給定用戶名和密碼,請使用authenticate()
它以關鍵字參數形式接收憑證,對於默認的配置它是username
和password,如果密碼對於給定的用戶名有效它將返回一個User對象。
如果密碼無效,authenticate()返回None。
例子:

from django.contrib.auth import authenticate 
user =
authenticate(username=‘john‘, password=‘secret‘) if user is not None: if user.is_active: print("User is valid, active and authenticated") else: print("The password is valid, but the account has been disabled!") else: print("The username and password were incorrect.")

如果authenticate返回正確的User對象,我們再使用login()方法,對返回的User對象進行登錄:

from django.contrib.auth import login
login(request,user)

這樣就完成了一個最基本的Django用戶認證。

如果我們要用其他的方式進行登錄認證呢,比如電子郵箱、手機號、或是本文所說的重點:微信openid,那就需要自定義認證方式。

在Django中進行自定義認證很是方便,完成一個自定義的認證只需要三步:
1、編寫一個認證後端:
一個認證後端是個實現兩個方法的類: get_user(user_id)和authenticate(**credentials)
在此,我們新建一個py文件wechatAuth.py來寫openid的認證後端:

from .models import Users
‘‘‘
    微信openid認證登錄
‘‘‘
class WechatOpenidAuth(object):
    def get_user(self,id_):
        try:
            return Users.objects.get(pk=id_)
        except Users.DoesNotExist:
            return None

    def authenticate(self,openid=None):
        try:
            user = Users.objects.get(openid=openid)
            if user is not None:
                return user
            return None
        except Users.DoesNotExist:
            return None

2、在配置文件setting.py中指定認證後端:
在底層,Django 維護一個“認證後臺”的列表。
當調用django.contrib.auth.authenticate() 時,Django 會嘗試所有的認證後臺進行認證。
如果第一個認證方法失敗,Django 將嘗試第二個,以此類推,直至試完所有的認證後臺。
使用的認證後臺通過AUTHENTICATION_BACKENDS 設置指定。

AUTHENTICATION_BACKENDS = (
‘django.contrib.auth.backends.ModelBackend‘,
‘website.wechat_auth.WechatOpenidAuth‘,
)
第一個認證後端是Django默認的認證方式,因為在Web端還需要使用,所以保留,第二個就是基於openid的認證後端。

3、使用自定義的認證後端處理登錄授權:
同樣的使用authenticate()方法和login()方法,但是我們只傳入一個參數進去,就是openid

from django.contrib.auth import login,authenticate
def auth(request,openid):
  try:
        auth =authenticate(openid=openid)
        login(request,auth)
        print("登錄成功",auth)
  except Exception as e:
        print(e)

這樣,一個基於openid的認證就完成了。

在微信的訂閱號中,我們可以利用click事件返回一個文本消息或圖文消息,在其鏈接之中帶上openid的參數。這樣,當用戶點擊鏈接,就可以靜默地完成用戶的登錄了。

=========================================================

原文信息

文章首發:http://zmister.com
原文鏈接
微信公眾號:州的先生 同步更新

使用Django實現微信公眾號用戶openid登錄認證