廖雪峰的python教程web实战学习笔记day17 vvipi 发表于2018年11月6日,阅读:2546 ### 注意! 本文只是学习笔记,不是最佳实践。博主python刚入门,在廖雪峰老师框架的基础上自行摸索改造,很可能写出了很多新bug。如果对文章内容有疑问,欢迎留言交流,但无法保证能够解决。 ### 选择微博授权登录的原因 - 你一个草根博客,还让人注册才能评论,谁有这闲工夫? - 搜索一番发现微信授权需要盖公章,个人博客很难实现。微博门槛相对较低。 - 廖老师也是微博授权登录。 ### 主要流程 1. 在微博开放平台注册为开发者,并创建一个网站接入app。https://open.weibo.com 这一步没有特别难的地方,搜索一下按流程操作即可。 ![](/download?fn=img_001541512498878fc73d7eb513a47228b8fe43ffe3a564d000) 2. 在博客代码中增加相应的功能,包括前端和后端。本文将介绍在廖老师的awesome web app基础上的开发方法。 以上两个步骤应该同时进行,因为等待审批需要时间,而开发也需要创建应用时获取的client_id和client_secret。 ### 解决思路 - 认证时与服务器api通信等部分已经有现成的解决方案,没有必要从头开发。这里经过搜索选择了可以用在python3环境的social-oauth第三方库。就是[这个版本](https://github.com/seasonstar/social-oauth "这个版本") - 整个认证过程主要包括下面几步: -- 生成一个链接,放在博客的某个页面上,推荐放在注册和登录页面。 -- 用户点击这个链接,跳转到新浪微博授权的页面,输入微博帐号或扫描登录来进行授权。 -- 页面自动跳转回我们在微博开放平台预留的**授权回调页**。 -- 授权回调页的后端代码调用socialoauth模块向新浪微博获取用户登录信息。成功的话就会取到用户信息,uid, name, avatar等。根据用户是否是首次登录,选择为其创建博客账号或者验证登录。 可以看出,由于使用了social-oauth第三方库,整个过程中需要我们写的代码其实很少,关键是理清新增的业务和框架原有的业务流程之间的关系。 ### 具体步骤 #### 1、下载文件 下载social-oauth源代码,这个项目支持国内主流的几个网站的授权登录,这里我们只需要用到新浪的部分,因此选择留下下面几个文件放在www文件夹下。weibo.png放在/static/img/下。 ![](/download?fn=img_001541512514838eed02396d739437c831d0ac09d045271000) 创建配置文件`site_setting.py`内容如下,其中的client_id和client_secret注册新浪微博公众平台,创建应用后可在“我的应用”中看到。 ``` SOCIALOAUTH_SITES = ( ('weibo', 'socialoauth.sites.weibo.Weibo', '新浪微博', { 'redirect_uri': 'http://www.wepin.online/oauth/weibo', # 改成你的授权回调页 'client_id': '你的id', 'client_secret': '你的client_secret', }), ) ``` #### 2、添加微博授权链接 修改signin.html和register.html,以及handler.py中的`@get('/register')`和`@get('/signin')`方法。 ```html <!-- 在signin.html和register.html中添加微博授权登录的链接 --> <p><a href={{authorize_url_weibo}}><img src="/static/img/weibo.png" /></a></p> ``` ```python from socialoauth import SocialSites, SocialAPIError from socialoauth.site_setting import SOCIALOAUTH_SITES # 相应修改handler.py中这两个网页的处理方法 @get('/register') def register(): socialsites = SocialSites(SOCIALOAUTH_SITES) url = socialsites.get_site_object_by_name('weibo').authorize_url return { '__template__': 'register.html', 'authorize_url_weibo': url, } @get('/signin') def signin(): socialsites = SocialSites(SOCIALOAUTH_SITES) url = socialsites.get_site_object_by_name('weibo').authorize_url return { '__template__': 'signin.html', 'authorize_url_weibo': url, } ``` #### 3、在数据库中为users表增加字段 为了区别微博授权登录的客户和网站注册用户,在users表中增加一个weiboid字段,用于保存用户的微博id。使用root用户登录,然后 ``` use awesome; alter table users add column `weiboid` varchar(50); ``` #### 4、添加授权回调页的处理方法 在微博工作平台-我的应用中设置: 授权回调页:`http://www.wepin.online/oauth/weibo` 取消授权回调页:`http://www.wepin.online/` 这样用户如果取消授权会跳回首页 修改handler.py: ```python from socialoauth import SocialSites, SocialAPIError from socialoauth.site_setting import SOCIALOAUTH_SITES @get('/oauth/weibo') async def oauth_weibo_callback(*, code): if not code: # error occurred return 'redirect:/oautherror' socialsites = SocialSites(SOCIALOAUTH_SITES) s = socialsites.get_site_object_by_name('weibo') try: s.get_access_token(code) except SocialAPIError as e: # 这里可能会发生错误 logging.info(e.site_name) # 哪个站点的OAuth2发生错误? logging.info(e.url) # 请求的url logging.info(e.error_msg) # 由站点返回的错误信息 / urllib2 的错误信息 raise # 到这里授权完毕,并且取到了用户信息,uid, name, avatar... users = await User.findAll('weiboid=?', [s.uid]) # 此用户第一次登录,为其创建本站账号 if len(users) == 0: uid = next_id() # 此处为了尽量不改原框架代码,走了个捷径,如有更规范的解决方案不妨分享一下。以用户id加盐的方式直接设置初始密码,以微博id@weibo.com格式直接设置个不存在的邮箱,不影响用户使用。 sha1_passwd = '%s:%s' % (uid, uid + _COOKIE_KEY) email = '%s@weibo.com' % s.uid user = User(id=uid, name=s.name.strip(), weiboid=s.uid, email=email, passwd=hashlib.sha1(sha1_passwd.encode('utf-8')).hexdigest(), image=s.avatar) await user.save() user.passwd = '******' # 已有账号 else: user = users[0] # 跳转回首页 r = web.HTTPFound('/') r.set_cookie(COOKIE_NAME, user2cookie(user, 86400), max_age=86400, httponly=True) user.passwd = '******' return r @get('/oautherror') def get_oautherror(): raise APIValueError('weibo', '新浪微博授权登录未成功.') ``` ### 总结 代码就这么点,等待新浪微博审核过程中,可以把自己的微博号添加到测试帐号中,先试试效果。感谢socialoauth库的作者!