使用Django实现微信公众号用户openid登录认证

浏览: 1793

最近在用Django做一个小项目,需要将微信的用户与网站的用户进行关联,由于是微信的订阅号,没有oauth网页授权的权限,只能退而求其次,在响应中获取用户的openid,来唯一的标识用户。

Django中用户的模型继承和扩展于AbstractUser,在用户模型中添加openid字段:
models.py

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

我们扩展了用户的模型,并使用这个模型来作为用户认证的模型,需要在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的参数。这样,当用户点击链接,就可以静默地完成用户的登录了。

推荐 1
本文由 州的先生 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

1 个评论

解释的很清楚。

要回复文章请先登录注册