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就是解決這樣的問題html
其實不少擁有大的資源信息的網站或者公司都有本身的開發平臺的,用來開放本身的一些資源信息,經過好比說auth2.0等一些折中的手段來達到擁有大的資源信息的網站或者公司和開發者的雙贏的局面,由於擁有大的資源信息的網站或者公司的能夠根據開發者開發出來的應用的類型來定向的判斷用戶類型,這樣以後,擁有大的資源信息的網站或者公司就能夠根據用戶是什麼類型的,定向的推送廣告,作大數據分析,與此同時,開發者也能達到開發出本身完整的應用的目的,真正的雙贏。python
先簡略的講一下auth2.0是怎麼工做的,這裏有一片好文章,你們能夠看一下,這裏我也講一下:linux
其實auth2.0工做有幾種模式:簡化模式,密碼模式,客戶端模式,受權碼模式,其中受權碼模式是使用最多的,這裏我就分析一下受權碼模式,qq開放互聯平臺就是使用這種模式,以下圖:git
首先明確一下角色,user-gent:用戶(或者能夠說是用戶瀏覽器); client:第三方網站或者應用; authorization server:認證服務器,它不是被第三方網站或者應用所擁有的,是放在原來的全部者(如騰訊)那裏的;resource owner:資源(如騰訊的qq用戶羣,爲騰訊所擁有)存放的地方,它是能夠和authorization server互通的;總共有四個對象。web
流程是這樣運轉的:ubuntu
步驟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,這以前的步驟對用戶來都是可見的,後面的步驟對用戶不可見;cookie
步驟D:這個時候用戶就來到了client這界面了,這個時候client就會獲取authorization code,若是有這個參數,表明用戶已經受權了,client就攜帶authorization code和redirect url訪問authentication server,向其索要訪問用戶信息的access tokenapp
步驟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)