网站用Django1.4,论坛用Discuz,用户系统共用Ucenter数据。
实现前台登录,到BBS上验证帐号,然后返回。成功,把信息存入django中!
给User models新增几个字段:
class UserProfile(models.Model): """ 用户信息 """ user = models.OneToOneField(User) uid = models.IntegerField(u'uid', unique=True, default=0)
然后再加个信号,这些官方doc中都有!
def create_user_profile(sender, instance, created, **kwargs): if created: UserProfile.objects.create(user=instance) post_save.connect(create_user_profile, sender=User)
接下来是用户登录使用所使用的 View:
1 def AuthViaBBS(username, password): 2 """ 3 在BBS数据库中查找用户数据 4 """ 5 HOST = '42.xx.xx.xx' 6 USER = 'xxxx' 7 PORT = 3306 8 PASSWD = 'xxxxxxx' 9 DBNAME = 'xxxxxx' 10 11 conn = '' 12 cursor = '' 13 try: 14 conn = MySQLdb.connect(host=HOST, port=PORT, passwd=PASSWD, user=USER, db=DBNAME ) 15 conn.set_character_set('utf8') 16 cursor = conn.cursor() 17 sql = "SELECT uid, username, password, email, salt FROM pre_ucenter_members where username='%s' limit 1" % username 18 result = cursor.execute(sql) 19 except Exception, e: 20 logger.error(u'远程BBS数据库连接失败! ' + str(e)) 21 finally: 22 conn.close() 23 data = {} # 返回的结果集 24 if result: # 有用户存在 25 (data['uid'], data['username'], data['password'], data['email'], data['salt']) = cursor.fetchone() 26 logger.info(u'BBS 中的用户信息: uid:%s username:%s password:%s email:%s salt:%s' % (data['uid'], data['username'], data['password'], data['email'], data['salt'] ) ) 27 if data['password'] and data['salt'] : 28 #验证密码 (md5(md5,salt)) 29 inputPwd = md5.new( md5.new(password).hexdigest()+data['salt'] ).hexdigest() 30 print inputPwd 31 if inputPwd == data['password']: 32 return data 33 return None 34 35 36 def isValid(str): 37 """ 38 检查str是否含有非法字符: ' " \ 39 """ 40 for i in str: 41 if i in ['\'','"','\\']: 42 return 0 43 return 1 44 45 def checkLogin(request): 46 username = request.POST.get('username','') 47 password = request.POST.get('password','') 48 logger.info(username+ ' ' + password) 49 if isValid(username) and isValid(password): 50 data = AuthViaBBS(username, password) 51 if data: 52 # 与本地数据库同步, 更新uid , email, salt 到本地 53 user = authenticate(remote_user = username) 54 if user: 55 user.email = data['email'] 56 user.save() 57 profile = user.get_profile() 58 profile.uid = data['uid'] 59 profile.save() 60 login(request, user) 61 return 'success' 62 else: 63 return u'更新本地数据失败!' 64 logger.error(u'更新本地数据失败! username:%s password:%s' % (username, password)) 65 else: 66 return u'帐号或密码错误!' 67 else: 68 return '帐号 或 密码含有非法字符'
接下来就是对密码验证方法的重写,默认是 ModelBackend (具体源码在django/contrib/auth/backends.py),我们改成 RemoteUserBackend ,不过这里我们要重写下,因为默认情况下,新建了无法发送信号,导致UserProfile无法新建,我们来看看关键的代码:
def authenticate(self, remote_user): ............... if self.create_unknown_user: user, created = User.objects.get_or_create(username=username) if created: user = self.configure_user(user) ................
我们改写成这样:
1 class DiscuzAuthBackend(RemoteUserBackend): 2 def authenticate(self, remote_user): 3 if not remote_user: 4 return 5 user = None 6 username = self.clean_username(remote_user) 7 8 if self.create_unknown_user: 9 try: 10 user = User.objects.get(username=username) 11 except User.DoesNotExist: 12 user = User.objects.create(username=username) 13 else: 14 try: 15 user = User.objects.get(username=username) 16 except User.DoesNotExist: 17 pass 18 return user
这样新建在新用户登录后,本地mysql数据库里没有,就新建该用户,同时出发信号,新建UserProfile !
最后在 Settings.py 新增这么几句:
AUTH_PROFILE_MODULE = 'account.UserProfile' AUTHENTICATION_BACKENDS = ( 'account.models.DiscuzAuthBackend', # 具体module位置看自己的项目 )
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django共享Ucenter用户数据库的简单实现 - Python技术站