Django實現oauth登陸-以微博爲例

做爲一個菜鳥,一直想了解並想實現一下經過oauth登陸本身的網站,加上最近工做中須要瞭解oauth,藉此把最近的理解和簡單的實現記錄下來,防止之後忘記。html

什麼是oauth:

在個人理解裏,oauth就是不經過本地的用戶信息,而是經過微博,微信等第三方的用戶信息登陸到本身的網站中。oauth受權有多種模式,我最近了解的是受權碼受權模式,微博的oauth2.0受權登陸也是根據這個模式。其餘模式能夠看https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html,說得很詳細,也容易懂。數據庫

步驟:django

在個人實現中,一共五個步驟:json

一、獲取受權碼codeapi

二、經過受權碼code獲取認證碼access_token微信

三、經過acess_token獲取微博端的用戶信息cookie

四、根據步驟3的用戶信息,與本地數據庫的用戶信息對比,實現本地登陸操做app

五、登陸完成,跳轉網頁函數

接下來,會根據以上5個步驟,結合微博受權登陸,給出用django實現的代碼與說明post

準備工做:

先到http://open.weibo.com/微博開放平臺,依次點擊網站接入-當即接入(記得要先登陸再點擊,要不會沒有反應),註冊一個應用,獲取app key和app secret,這兩個東西是步驟一、2中的關鍵參數。

當你登陸並建立應用後,能夠在 個人應用-應用信息-基本信息 中找到這兩個東西,接下來就能夠進行開發了。

一、獲取受權碼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 受權設置中進行設置,要不回調時會報錯。

二、獲取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,能夠經過這個獲取用戶信息,其餘返回參數意義可看官方文檔。

三、獲取用戶信息:

直接上代碼:

文檔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

四、實現本地登陸:

本地登陸不是必須的,你能夠在微博端認證完畢後,再也不在本地進行驗證,而直接設置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()
# 接下來是你的網站的登陸處理,你有兩種選擇:
    #   一、你能夠不作任何處理,只要用戶成功登陸了微博,就直接跳轉到你的網站首頁。
    #   二、你能夠對比本地數據庫,看是否存在該用戶,若是存在則直接跳轉,不存在能夠提示用戶綁定你的網站的帳號,或者直接用
    #       微博用戶信息做爲該用戶在你本地的帳號
    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這個步驟的,這個步驟是給咱們處理一些東西用的。

 

以上僅僅是我我的的理解,也是第一次寫博客,若是有寫得很差或寫錯的地方,歡迎指出

相關文章
相關標籤/搜索