三方登入原理及後端示例程式碼
原理圖
拿微博示例:
注意,此時後端有三個介面,分別為,獲取掃碼url的介面,驗證是否為繫結使用者的介面,繫結介面
- 注意,驗證是否為繫結使用者的介面並沒有繫結介面的功能
1.1 前端獲取認證code
1.在Vue頁面載入時 動態傳送請求獲取微博授權url
2.django收到請求的url後,通過微博 應用ID(client_id)和回撥地址(redirect_uri) 動態 生成授 權url返回給Vue
3.當使用者點選上面的url進行掃碼,授權成功會 跳轉我們的回撥介面並附加code引數
4.Vue獲取到微博返回的code後,會 將code傳送給django後端 (上面的redirect_uri)
1.2 獲取微博access_token
後端獲取code後,結合client_id、client_secret、redirect_uri引數進行傳遞,獲取微博 access_token
1.3 獲取微博使用者基本資訊並儲存到資料庫
使用獲得的access_token呼叫獲取使用者基本資訊的介面, 獲取使用者第三方平臺的基本資訊
使用者基本資訊 儲存到資料庫,然後關聯本地使用者 ,然後將使用者資訊返回給前端
1.4 生成token給Vue
django後端藉助微博認證成功後,可以 使用JWT生成token ,返回給Vue
Vue將token儲存到localStorage中 ,以便使用者訪問其他頁面進行身份驗證
2.第三方登入與本地登入的關聯(三種情況)
2.1 情況1: 本地未登入,第一次登入第三方
此時相當於註冊,直接把第三方資訊拉取來並註冊成本地使用者就可以了,並建立本地使用者與第三方使用者(openid)的繫結關係
2.2 情況2**:本地未登入,再次登入第三方**
此時使用者已註冊,獲取到openid後直接找出對應的本地使用者即可
2.3 情況3**:本地登入,並繫結第三方**
這個只要將獲取到的openid繫結到本地使用者就可以了
3.oauth認證原理
OAuth是一個開放標準,允許使用者讓第三方應用訪問該使用者在某一網站上儲存的私密的資源,而無需將使用者名稱和密碼提供給第三方應用。
OAuth允許使用者提供一個令牌,而不是使用者名稱和密碼來訪問他們存放在特定服務提供者的資料。
這個code如果能出三方換取到資料就證明這個使用者是三方真實的使用者
4.為什麼使用三方登入
服務方希望使用者註冊, 而使用者懶得填註冊時的各種資訊(主要是為了保證使用者的唯一性,各種使用者名稱已佔用,密碼格式限制).
而像微信, QQ, 微博等幾乎每個人都會安裝的應用中使用者肯定會在其中某一個應用中已經註冊過,證明該使用者在已經註冊的應用中的唯一性.
第三方登入的實質就是在授權時獲得第三方應用提供的代表了使用者在第三方應用中的唯一性的openid.並將openid儲存在第三方服務控制的本地儲存.
就是在授權時獲得第三方應用提供的代表了使用者在第三方應用中的唯一性的openid.並將openid儲存在第三方服務控制的本地儲存.
註冊微博
地址:https://open.weibo.com/
回撥頁面是指掃碼後,攜帶code碼返回給前端的url地址,在後端的獲取掃碼url介面中和微博後臺中一致
使用微博使用者code+微博開發者賬號資訊換取微博的認證access_token
獲取url介面程式碼
class WeiboUrl(APIView):
# 自定義許可權類
permission_classes = (AllowAny,)
def post(self, request):
url = 'https://api.weibo.com/oauth2/authorize?'
data = {
'client_id':'1006916973',
'response_type':'code',
'redirect_uri':'http://127.0.0.1:8888/oauth/callback',
}
weibo_url = url + urlencode(data)
return Response({'code':'0','msg':'成功','data':{'url':weibo_url}})
回撥介面
class OauthWeiboCallback(APIView):
# 自定義許可權類
permission_classes = (AllowAny,)
def post(self, request):
# 接收vue端傳過來的code(微博的使用者code)
# 1.使用微博使用者code+微博開發者賬號資訊換取微博的認證access_token
code = request.data.get('code')
data = {
'client_id':'1006916973',
'client_secret':'b089ebeb447f4def683ef737c2ed762c',
'grant_type':'authorization_code',
'code':code,
'redirect_uri':'http://127.0.0.1:8888/oauth/callback',
}
url = 'https://api.weibo.com/oauth2/access_token'
data = requests.post(url=url, data=data).json()
access_token = data.get('uid')
weibo_uid = data.get('access_token')
# 2. 根據uid 查詢繫結情況
try:
oauth_user = OauthUser.objects.get(uid=weibo_uid, oauth_type='1')
except Exception as e:
oauth_user =None
# 返回動作, 登陸成功/需要繫結使用者 type=0 登陸成功, 1,授權成功,需要繫結
if oauth_user:
# 4. 如果繫結了,返回token, 登入成功
user = oauth_user.user
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
# jwt_response_payload_handler為user模組定義的jwt返回的資訊
data = jwt_response_payload_handler(token, user)
data['type'] = '0' # 指定為登陸成功
return Response({'code':0, 'msg':'登入成功', 'data':data})
else:
# 5.如果沒繫結,返回標誌,讓前端跳轉到繫結頁面
return Response({'code':0, 'msg':'授權成功', 'data':{'type':'1', 'uid':weibo_uid}})
繫結介面
class OauthWeiboBindUser(APIView):
permission_classes = (AllowAny,)
def post(self,request):
# 繫結使用者, 1.已註冊使用者, 2.未註冊使用者
# 1.1 獲取使用者名稱, 密碼,weibo_uid
username = request.data.get('username')
password = request.data.get('password')
weibo_uid = request.data.get('weibo_uid')
if not all([username,password,weibo_uid]):
return Response({'code':999, 'msg':'引數不全'})
# 0.判斷是否存在此使用者
try:
user = User.objects.get(username=username)
except Exception as e:
user = None
# 1.已註冊使用者
if user:
#1.2 如果存在就驗證密碼,驗證通過,就繫結,返回token,登陸成功
if user.check_password(password):
ou = OauthUser(uid=weibo_uid,user=user,oauth_type='1')
ou.save()
payload = jwt_payload_handler(user) # 通過user物件獲取到jwt的payload資訊
token = jwt_encode_handler(payload) # 生成token
data = jwt_response_payload_handler(token, user)
data['type'] = '0' # 指定為登陸成功
return Response({'code':0,'msg':'登陸成功','data':data})
else:
return Response({'code':999, 'msg':'密碼錯誤'})
else:
# 2. 未註冊使用者
# 2.1 生成新使用者,設定使用者名稱密碼,儲存,然後繫結,返回token,登陸成功
user = User(username=username)
user.set_password(password)
user.save()
ou = OauthUser(uid=weibo_uid,user=user, oauth_type='1')
ou.save()
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
data = jwt_response_payload_handler(token, user)
data['type'] = '0' # 指定為登陸成功
return Response({'code':0, 'msg':'登陸成功','data':data})
yload_handler(token, user)
data[‘type’] = ‘0’ # 指定為登陸成功
return Response({‘code’:0, ‘msg’:‘登陸成功’,‘data’:data})
相關文章
- iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例iOS
- App 第三方登入獲取使用者資訊 支付寶登入後端程式碼參考APP後端
- 第三方登入原理
- GitHub OAuth 第三方登入示例教程GithubOAuth
- 單點登陸原理及程式碼(CAS)
- 前後端分離下的第三方登入後端
- SSH遠端登入原理
- App 掃碼登入 pc 端(不是微信第三方掃碼登入)怎麼實現?APP
- JSP程式設計實現簡單使用者7天內免登入及示例程式碼JS程式設計
- PbootCMS程式後臺登入密碼重置工具boot密碼
- 小程式授權登入前後端對接及使用者資訊完善後端
- Android端程式碼染色原理及技術實踐Android
- 第三方登陸:微信掃碼登入
- 聊聊“密碼登入”、“手機快捷登入”和“第三方聯合登入”密碼
- 掃碼登入認證技術原理介紹及實踐
- RCE(遠端程式碼執行漏洞)原理及漏洞利用
- JSP程式設計實現使用者自動登入功能示例程式碼JS程式設計
- Opencv及常用方法示例程式碼OpenCV
- 微信掃小程式碼實現網頁端登入網頁
- WebSocket 前後端示例Web後端
- ABtest原理及python程式碼Python
- 淺析微信掃碼登入原理
- 二維碼掃碼登入是什麼原理
- 前後端分離專案OAuth第三方登入怎麼做(以Github舉例)後端OAuthGithub
- SSH 遠端登入「記住密碼」密碼
- PbootCMS後臺登陸密碼忘記/找回後臺登入密碼外掛boot密碼
- 建築後端程式碼後端
- PbootCMS後臺登陸密碼忘記/找回密碼後臺登入密碼外掛boot密碼
- DES原理及程式碼實現
- 單點登入原理
- 純css實現輸入框placeholder動效及輸入校驗的示例程式碼CSS
- sessionid是在後端程式碼HttpServletRequest的getSession的時候建立,那麼怎麼在後端(即登入攔截器中)獲取sessionid?Session後端HTTPServlet
- 一圖搞懂掃碼登入的技術原理
- 獲取登入驗證碼失敗及前後端不同域導致session丟失問題分析記錄後端Session
- 前後端分離使用 Token 登入解決方案後端
- 前後端實現登入token攔截校驗後端
- Avalonia 後臺程式碼簡單播放動畫示例動畫
- 面試官:聊聊微信和淘寶掃碼登入背後的實現原理?面試