Auth是一個開放協議,允許用戶讓第三方應用以安全且標准的方式獲取該用戶在某以網站,移動或桌面應用上存儲的司名的資源(如用戶個人信息,照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。
OAuth2.0是OAuth協議的升級版本,關注客戶端開發者的簡易性,同時為Web應用,桌面應用及收集和起居室設備提供專門的認證流程。
OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問它們存放在特定服務提供者的數據。每一個令牌授權一個特性的網站在特定的時段內訪問特定的資源。這樣Oauth允許用戶授權第三方網站訪問它們存儲在另外的服務提供者上的信息,而不需要分享它們的訪問許可或它們數據的所有內容。
授權過程:
- 用戶關注微信公眾賬號
- 微信公眾賬號提供用戶請求授權頁面URL (開發者需要先到公眾平台官網中的“開發 - 接口權限 - 網頁服務 - 網頁帳號 - 網頁授權獲取用戶基本信息”的配置選項中,修改授權回調域名。請注意,這里填寫的是域名(是一個字符串),而不是URL,因此請勿加 http:// 等協議頭;)
- 用戶單擊授權頁面URL,向服務器發起請求
- 服務器詢問用戶是否同意授權給微信公眾賬號(scope 為snapi_base時無此步驟)
- 用戶同意 (scope 為snapi_base時無此步驟)\
- 服務器將code通過回調傳給微信公眾號
- 微信公眾賬號獲得code
- 微信公眾號通過code向服務器請求access token
- 服務器返回Access Token 和OpenID給微信公眾號
- 微信公眾賬號通過Access Token 向服務器請求用戶信息(scope 為snsapi_base時無此步驟)
- 服務器將用戶信息會送給微信公眾賬號(scope 為snsapi_base時無此步驟)
實現 3):
把認證的鏈接推送給用戶:
elif isinstance(recMsg,ReceiveTextMsg): #測試 Oauth認證 content = '<a href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx349372b8988f6776&redirect_uri=http://ahmay.ngrok2.xiaomiqiu.cn/&response_type=code&scope=snsapi_base&state=1#wechat_redirect">' \ '單擊這里體驗OAuth授權</a>' # replyMsg = ReplyTextMsg(recMsg.FromUserName,recMsg.ToUserName,recMsg.Content) replyMsg = ReplyTextMsg(recMsg.FromUserName, recMsg.ToUserName, content)
scope:
snsapi_base: 單擊鏈接后,不會彈出授權頁面
snsapi_userinfo:單擊鏈接后,會彈出授權頁面
單擊后,重定向的鏈接里面會包含 code和state參數. (開發者可以填寫任意state參數)
實現 8)用code換access_token
def exchange_access_token(code): exchange_url = ' https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code'.format( wechat_Const.appId,wechat_Const.appSecret,code ) response = requests.get(exchange_url) return json.loads(response.text)
返回:
{'access_token': '28_HVHo_-O6ijddWk2tesCOoyNQZOBudlByenwX5s9jTQxaz5bl5MEDXOGyM_UnP83FMiZv8L85EHjo2atet3Dgf_1HJy4yzZnMPz5Aci3kEwo', 'expires_in': 7200, 'refresh_token': '28_a3YKiuKaeQhx5rGx9jCYn6NyrFycQwBgq25ofsIiqYWf0lcn2VL3uNqK6LgKBLwEgZiNGCKrAATn5QqDgAzVBP9-pwn9nheMRXogEe_jxrM', 'openid': 'o-TXmsiCVUNT0iDRRaiW8iTxhx4Q', 'scope': 'snsapi_userinfo'}
當 access_token超時后,可以使用refresh_token進行刷新,refresh_token 擁有較長的有效期(7天,30天,60天,90天),當refresh_token失效后,需要用戶重新授權.
def refresh_access_token(refresh_token): refresh_url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={0}&grant_type=refresh_token&refresh_token={1}'.format( wechat_Const.appId,refresh_token ) response = requests.get(refresh_url) return json.loads(response.text)
返回同樣格式的json數據。
實現 10)使用access_token獲取用戶信息(scope 為snsapi_userinfo)
def query_userinfo(access_token,openid,lang='zh_CN'): query_url='https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang={2}'.format( access_token,openid,lang ) response = requests.get(query_url) return json.loads(response.content)
驗證 access_token是否有效的實踐:
def very_access_token_valid(access_token,openid): very_url = 'https://api.weixin.qq.com/sns/auth?access_token={0}&openid={1}'.format(access_token,openid) response = requests.get(very_url) result = json.loads(response.text) if result['errcode'] == 0: return True else: return False