作為一個菜鳥,一直想了解並想實現一下通過oauth登錄自己的網站,加上最近工作中需要了解oauth,借此把最近的理解和簡單的實現記錄下來,防止以后忘記。
什么是oauth:
在我的理解里,oauth就是不通過本地的用戶信息,而是通過微博,微信等第三方的用戶信息登錄到自己的網站中。oauth授權有多種模式,我最近了解的是授權碼授權模式,微博的oauth2.0授權登錄也是根據這個模式。其他模式可以看https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html,說得很詳細,也容易懂。
步驟:
在我的實現中,一共五個步驟:
1、獲取授權碼code
2、通過授權碼code獲取認證碼access_token
3、通過acess_token獲取微博端的用戶信息
4、根據步驟3的用戶信息,與本地數據庫的用戶信息對比,實現本地登錄操作
5、登錄完成,跳轉網頁
接下來,會根據以上5個步驟,結合微博授權登錄,給出用django實現的代碼與說明
准備工作:
先到http://open.weibo.com/微博開放平台,依次點擊網站接入-立即接入(記得要先登錄再點擊,要不會沒有反應),注冊一個應用,獲取app key和app secret,這兩個東西是步驟1、2中的關鍵參數。
當你登錄並創建應用后,可以在 我的應用-應用信息-基本信息 中找到這兩個東西,接下來就可以進行開發了。
1、獲取授權碼code:
我們可以在很多網站的登錄頁看到QQ,微博等登錄圖標,當我們點一下,就會彈框或跳轉到相應的第三方登錄頁,然后輸入QQ或微博賬號,登錄成功后會再跳轉到某個頁面,這當中就包含了獲取授權碼code的過程了。我們先創建一個頁面login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="https://api.weibo.com/oauth2/authorize?client_id=app_key&response_type=code&redirect_uri=http://127.0.0.1:8000/process"> 微博登錄 </a> </body> </html>
這里的微博登錄可以換成微博小圖標,點擊就會跳轉到微博的登錄頁。這里解釋一下參數,client_id的值就是准備工作中得到的app key,response_tye為固定值,redirect_uri的值為登錄成功后要跳轉的頁面,一般來說,這個值不會是最終要跳轉的頁面,而是作為一個中間值,用來處理微博用戶信息與本地用戶信息的關系,並實現本地的登錄。視圖函數中的代碼:
def login(request): return render(request, "login.html")
很簡單的一個函數,僅僅是渲染一下登錄頁面。
當在微博登錄頁登錄成功后,會以redirect_uri?code=xxxx(本例子中為
http://127.0.0.1:8000/process?code=xxxxx
)的方式回調你所填的uri,這時就可以獲取到授權碼code了,需要注意的是,回調的redirect_uri需要在 我的應用-應用信息-高級信息-OAuth2.0 授權設置中進行設置,要不回調時會報錯。
2、獲取acess_token:
acess_token不僅僅可以用來獲取微博的用戶信息,還可以調用微博提供的其他api,詳情可以看官方文檔http://open.weibo.com/wiki/。首先看獲取token的代碼:
def get_token(code): """ 獲取access_token http://open.weibo.com/wiki/Oauth2/access_token """ app_key = app_key app_secret = app_secret token_url = "https://api.weibo.com/oauth2/access_token" params = { "client_id": app_key, "client_secret": app_secret, "grant_type": "authorization_code", "code": code, "redirect_uri": "http://127.0.0.1:8000/process" } result = requests.post(url=token_url, data=params) return result
主要看params中的參數,這些都是獲取access_token的必須參數,code為步驟1中獲取到的授權碼,grant_type在授權碼模式中就是這個固定值,redirect_uri要與步驟1中的一樣,詳情可看文檔 http://open.weibo.com/wiki/Oauth2/access_token,返回的結果如下:
{'access_token': 'xxxxxxxxxx', 'remind_in': '157679999', '
expires_in': 157679999, 'uid': '392039283', 'isRealName': True}
uid是登錄微博用戶的id,可以通過這個獲取用戶信息,其他返回參數意義可看官方文檔。
3、獲取用戶信息:
直接上代碼:
文檔https://api.weibo.com/2/users/show.json
def get_user_info(result): """ 獲取用戶信息 """ get_user_url = "https://api.weibo.com/2/users/show.json" uid = result["uid"] access_token = result["access_token"] user_info = requests.get(url=get_user_url, params={"access_token": access_token, "uid": uid}) return user_info
函數參數中的result是步驟2中的result,獲取用戶信息的必要兩個參數是access_token和uid
4、實現本地登錄:
本地登錄不是必須的,你可以在微博端認證完畢后,不再在本地進行驗證,而直接設置cookies,然后跳轉到最后的登錄頁,比如網站的首頁。我們這里不這樣做,而是進行本地驗證,代碼如下:
def process(request): code = request.GET.get("code") result = get_token(code) # 獲取access_token和用戶uid result = result.json() # 將json格式字符串轉化為字典對象 user_info = get_user_info(result).json() # 接下來是你的網站的登錄處理,你有兩種選擇: # 1、你可以不做任何處理,只要用戶成功登錄了微博,就直接跳轉到你的網站首頁。 # 2、你可以對比本地數據庫,看是否存在該用戶,如果存在則直接跳轉,不存在可以提示用戶綁定你的網站的賬號,或者直接用 # 微博用戶信息作為該用戶在你本地的賬號 return redirect("/index")
這是一個視圖函數,是處理步驟1中http://127.0.0.1:8000/process,這個回調uri的,可以看到我們獲取了授權碼code,然后獲取access_token和uid(步驟2),接着獲取用戶信息(步驟3),接下來的驗證要根據自己的實際情況進行。最后所有東西處理完畢后,重定向到首頁index去。
最后是django,urls.py中的代碼:
from django.conf.urls import url from django.contrib import admin from django_app import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^process/', views.process), url(r'^index/', views.index), ]
最后總結一下,在用戶看來,整個過程只有兩步,第一步是跳轉到微博登錄頁,用戶輸入賬號密碼;第二步是跳轉到指定url(這個url不是redirect_uri),這個url可以是網站首頁,也可以是綁定本地網站賬號頁,用戶是看不到跳轉redirect_url即http://127.0.0.1:8000/process這個步驟的,這個步驟是給我們處理一些東西用的。
以上僅僅是我個人的理解,也是第一次寫博客,如果有寫得不好或寫錯的地方,歡迎指出
