徒手构建auth2.0验证平台(以qq为例)

auth2.0的功用:首先说一下为什么需要auth2.0,auth2.0是开放平台互联协议,可以这样理解,A是行业中的小生,两手空空;B是行业大佬,财大气粗,有一大批人(用户群);这个时候A需要借用B的用户群信息来构建自己的项目中的某项功能,但是出于资源的保护和各方面原因,B不相信A,不会让A接入自己的信任体系里面,A是无法直接获取B那边用户群的用户名和密码的,同时A又想借用B拥有的用户群信息来完善自己项目中的某些功能,这个时候就需要auth2.0来做中介,通过一些业务流程来实现A在没有B的用户群的直接信息(账户和密码),可以间接的获取到B那边的用户群的其他信息(除了用户名和密码,如用户昵称等等),至于信息的开发程度,那得看B了。说白了就是如何使得A在没有B的用户群的密码和账号的情况下获取B的用户群的其他的信息,auth2.0就是解决这样的问题

其实很多拥有大的资源信息的网站或者公司都有自己的开发平台的,用来开放自己的一些资源信息,通过比如说auth2.0等一些折中的手段来达到拥有大的资源信息的网站或者公司和开发者的共赢的局面,因为拥有大的资源信息的网站或者公司的可以根据开发者开发出来的应用的类型来定向的判断用户类型,这样之后,拥有大的资源信息的网站或者公司就可以根据用户是什么类型的,定向的推送广告,做大数据分析,与此同时,开发者也能达到开发出自己完整的应用的目的,真正的共赢。

先简略的讲一下auth2.0是怎么工作的,这里有一片好文章,大家可以看一下,这里我也讲一下:

其实auth2.0工作有几种模式:简化模式,密码模式,客户端模式,授权码模式,其中授权码模式是使用最多的,这里我就分析一下授权码模式,qq开放互联平台就是使用这种模式,如下图:

首先明确一下角色,user-gent:用户(或者可以说是用户浏览器); client:第三方网站或者应用; authorization server:认证服务器,它不是被第三方网站或者应用所拥有的,是放在原来的所有者(如腾讯)那里的;resource owner:资源(如腾讯的qq用户群,为腾讯所拥有)存放的地方,它是可以和authorization server互通的;总共有四个对象。

流程是这样运转的:

步骤A:先是user-agent访问client,client需要确定user-agent是谁,但是client没有user-agent的用户和密码,无法验证验证用户,所以将user-agent通过A步骤将重定向(导向)到authorization-server那里(如果是client是通过qq来验证用户,这个时候用户就会发现自己的浏览器跳到qq登录的界面),同时重定向过程中也会附带一些信息,方便后面的操作,这个步骤最重要的信息就是redirect url和client identifier这两个参数

步骤B(user authentication):用户在登录界面就会输入用户名和密码给authorization server,authorization server发现用户名和密码正确,发现确实有这个用户存在,就会要用户是否授权给client给访问他的个人信息

步骤C:得到了用户的允许之后,authorization server就会根据步骤A得到redirect url将用户重定向到client那里,同时携带authorization code和一些其他的信息给client,这之前的步骤对用户来都是可见的,后面的步骤对用户不可见

步骤D:这个时候用户就来到了client这界面了,这个时候client就会获取authorization code,如果有这个参数,代表用户已经授权了,client就携带authorization code和redirect url访问authentication server,向其索要访问用户信息的access token

步骤E:如果authorization code没有是有效的,authorization server就会将access token发给client,同时access token是有期限的

步骤F:cleint就会携带得到的access token去访问resource owner,由于resource owner和authorization server是互通的,所以resource owner可以验证access token是否有效或者过期,如果有效和没有过期,那么就会允许client访问之前那个用户的一些信息了。

其实上面都是看文档得来的

好了,讲了auth2.0(其实肯定由auth1.0,有兴趣可以自己去了解)流程之后,下面就是实现了。

环境:tornado, linux(linux mint 类ubuntu),新浪云,qq互联验证平台

新浪云申请免费域名之用,因为qq互联验证平台要一个真正的域名,不像优酷开发平台直接上一个ip地址就可以了。

先讲一下新浪云怎么申请免费域名(又到了看文档的时候了),这样子吧,先来图:

看到了上面的创建应用的按钮了吗?那就是你可以申请域名的按钮了,新浪云原理是这样子的,就是你将你的小应用开发好,然后将你的应用调试成其要求的环境,通过git或者svn这类的版本控制器将你的应用传到其要求的地方,然后你就可以通过其给你自定义的域名(域名是你创建的应用的时候,你自己指定的,我这里指定的是zhougch501.sinaapp.com)来访问你的应用了,其间的部署的工作,sina云已经帮你做好了,你不用担心,方便不?

这之间有几个要注意地方:1.如何通过git或者svn来将自己的应用传上去,可以看这里,我个人推荐使用git,如果不会使用git,可以看这里,好了,我就创建一个应用做示范吧

当然先是点击创建应用按钮,这里我创建的应用是zhougch502

点击创建之后:

选择开发语言python2.7

然后就是创建罗,创建成功了之后就要进入应用的管理界面了,进入应用管理界面之后就可以点击代码管理了,然后他就会让你选择是git还是svn,这里我选择的是git了

选择了git了之后就会在页面中显示如何将将代码上传到新浪云了,页面最下面的蓝色的链接有更细的说怎么做,你可以去看一下。

 

            2.如何将自己的应用调试新浪云要求的环境,这里面有详细的介绍(又到了看文档的时候了)

 

ok,到了讲解如何使用新浪云给的域名来在qq互联平台使用qq来实现auth2.0的认证流程,这里有了上面我讲解auth2.0的知识准备,这里就简单多了

先是看qq互联平台给的auth2.0文档,为什么还要看文档^~^,因为qq互联平台对auth2.0标准认证流程做了一些改动,同时qq互联平台提供了两种接入方式,有网站接入和app接入,这里我讲解的是网站的接入。好了,在这个之前,我还要做一些准备工作。看这里 ,其实就是在qq互联平台上里面创建一个应用,和在新浪云里面一样,有木有,哈哈哈。流程截图如下:

 

看到了申请地址了没有,进入了之后就可以点击管理中心了,然后点击创建应用,然后选择应用类型为网站:

 

然后就是应用的信息填写,里面的信息怎么填写,填写界面都给出相应的信息和文档(又要看文档,醉了),里面网站地址就是之前在新浪云上面免费申请的网址,看到了吧,之前的工作是有用的

好了,这之后就有了qq互联平台的appid和appkey,不知道appid和appkey的孩子们,看这里,在未审核项里面就有你的刚刚创建的应用

 

点击你的应用进去之后就可以看到你的appid和appkey了

 

ok,准备工作已经完成了,然后你就可以根据我之前讲的auth2.0知识来参考qq互联给的文档来实现使用qq登录让用户授权来获取用户信息。qq互联平台上也有代码示例,是使用PHP来实现的,会写程序的人都能看得懂的。

然后就是最后我的实现,大家可以点击这里试一下。

下面我在linux使用tornado(python)实现代码,可以参考一下,注意:这里代码是部署到新浪云的代码了

# -*- coding: utf-8 -*-

import tornado.wsgi
import os.path
import httplib
import urllib
import urllib2
import sae


from urllib import quote
class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("username")

class LoginHandler(BaseHandler):
    def get(self):
        self.render('login.html')

class WelcomeHandler(BaseHandler):
    # get code 
    def get(self):
        if self.get_argument("code", None) and str(self.get_argument("state", None)) == "test":
            # get token
            code = self.get_argument("code")
            redirect_url = quote("http://zhougch501.sinaapp.com/")
            req_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=101265051&client_secret=b238da816c4e4dcb598836084dcea067&redirect_uri=" + redirect_url + "&code=" + code
            req = urllib2.Request(req_url)
            res_data = urllib2.urlopen(req)
            res = res_data.read()
            res = res.split("&")
            access_token = res[0].split("=")
            access_token = access_token[1]

            # 获取用户的openid
            req_url = "https://graph.qq.com/oauth2.0/me?access_token=" + access_token 
            req = urllib2.Request(req_url)
            res_data = urllib2.urlopen(req)
            res = res_data.read()

            # get openid
            # callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} )
            res = res.split(",")
            res = res[1].split(":")
            res = res[1].split("\"")
            openid = res[1]


            # 获取用户的信息
            req_url = "https://graph.qq.com/user/get_user_info?access_token=" + access_token + "&oauth_consumer_key=101265051&openid=" + openid
            req = urllib2.Request(req_url)
            res_data = urllib2.urlopen(req)
            res = res_data.read()
            res.replace("{", "")
            res.replace("\"", "")
            res = res.split(",")
            name = ""
            # info = {}
            for index in range(len(res)):
                if index == 3:
                    name = (res[index].split(":"))[1]
            self.render("index.html", info=name)

        else:
               if self.current_user:
                   self.render('index.html', user=self.current_user)
               else:
                   self.redirect("/login")

class LoginQQHandler(BaseHandler):
    def get(self):
        redirect_url = quote("http://zhougch501.sinaapp.com/")
        req_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=101265051&redirect_uri=" + redirect_url + "&state=test"
        self.redirect(req_url)

class LogoutHandler(BaseHandler):
    def get(self):
    # if (self.get_argument("logout", None)):
        self.clear_cookie("username")
        self.redirect("/")

        

settings = {
        "template_path": os.path.join(os.path.dirname(__file__), "templates"),
        "static_path": os.path.join(os.path.dirname(__file__), "static"),
        "cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=",
        "xsrf_cookies": True,
        "login_url": "/login"
    }

app = tornado.wsgi.WSGIApplication([
        (r'/', WelcomeHandler),
        (r'/login', LoginHandler),
        (r'/loginWithQQ', LoginQQHandler),
        (r'/logout', LogoutHandler)
    ], **settings)

application = sae.create_wsgi_app(app)

 

转载于:https://www.cnblogs.com/zhougch/p/4974103.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值