轉(zhuǎn)自:https://blog.csdn.net/qq_29757283/article/details/86539882
本文配置部分主要參考 django-rest-auth 官方文檔 ?
另外添加了一些不同的使用方式:
({HTTPie,Curl}×{key,cookie}{\text{HTTPie}, \text{Curl}} \times {\text{key}, \text{cookie}}{HTTPie,Curl}×{key,cookie})
token(key) cookie
獲取值 3.2.1 3.3.1
HTTPie 3.2.2.2 3.3.2.1
Curl 3.2.2.1 3.3.2.2
Overview
Configuration
1.1 django-rest-auth
1.2 django-rest-framework驗(yàn)證
2.1 It Works
3 使用 rest_auth 獲取認(rèn)證倾剿,訪問
3.1 了解 rest_auth 如何獲取認(rèn)證
3.2 使用認(rèn)證的 token 訪問數(shù)據(jù)
3.2.1 獲取 token(key) value
3.2.1.1 curl 工具
3.2.1.2 HTTPie
3.2.2 使用賬號(hào)的 token 訪問 model(REST API)
3.2.2.1 curl
3.2.2.2 HTTPie
3.2.2.3 POSTman 軟件
3.2.2.4 基于 requests 庫(kù)的 Python 代碼
3.3 使用登錄后 Set 的 Cookie 訪問數(shù)據(jù)
3.3.1 登錄和 Set-Cookie
3.3.2 使用 Cookie 訪問數(shù)據(jù)
3.3.2.1 HTTPie
3.3.2.2 Curl
延伸
ReferenceConfiguration
1.1 django-rest-auth
因?yàn)?rest-auth 庫(kù)基于 DRF1聋袋,所以首先要安裝 DRF 我就不多說(shuō)了
pip install dango-rest-auth
<proj>/api/urls.py
嚴(yán)謹(jǐn)來(lái)說(shuō),哪個(gè) urls.py 文件取決于您如何設(shè)計(jì)項(xiàng)目源碼結(jié)構(gòu)纫塌,以及這個(gè)項(xiàng)目結(jié)構(gòu)如何對(duì)應(yīng) rest api苛萎。所以實(shí)際上每個(gè)人自己修改的 urls.py 未必相同桨昙。
(可以直接修改和 settings.py 同一路徑下的 urls.py,代碼和下面一樣腌歉,這樣就可以像下文一樣訪問 http://<domain>:[port]/api/rest_auth/login/ 了)
urlpatterns += [
path('api/rest_auth/', include('rest_auth.urls')),
]
1
2
3
<proj>/<proj>/settings.py :
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#
# install
#
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
[...]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1.2 django-rest-framework
<proj>/<proj>/settings.py
[...]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
[...]
1
2
3
4
5
6
7
8
9
10
11
12
13
直接添加上面段落蛙酪。
這一段非常重要,如果沒有這一段的化翘盖,那么可能使用正確的認(rèn)證方式(比如下面用到的 user’s key in tokens)也無(wú)法訪問成功桂塞。
- 驗(yàn)證
2.1 It Works
現(xiàn)在直接通過(guò) DRF 提供的 rest api 訪問 model 將會(huì)失敗(要求權(quán)限認(rèn)證)馍驯。
3 使用 rest_auth 獲取認(rèn)證阁危,訪問
3.1 了解 rest_auth 如何獲取認(rèn)證
post manage.py createsuperuser 的賬號(hào)密碼到 django-rest-auth 的 end-point(即 API),獲得到 token(rest_auth 使用“key” 表示):
POST 正確的賬號(hào)密碼之后汰瘫,現(xiàn)在就可以繼續(xù)使用瀏覽器訪問其它編寫的 endpoint(REST API)狂打,比如 DRF 官方實(shí)現(xiàn)了一個(gè) Snippet model 用作 Tutorial,瀏覽器在 rest_auth 登錄之后吟吝,就可以訪問 http://<domain>:[port]/api/snippet/菱父。
(這是因?yàn)闉g覽器已經(jīng) Set-Cookie 過(guò)了,下文會(huì)講到。)
3.2 使用認(rèn)證的 token 訪問數(shù)據(jù)
3.2.1 獲取 token(key) value
token 意思是 user’s key 的集合官辽。在 Django 的 admin 后臺(tái)管理中可以看到:
通過(guò)瀏覽器訪問 rest_auth 的 rest api 獲取 token 的方式我們已經(jīng)在 3.1 節(jié)看過(guò)了。
當(dāng)然粟瞬,實(shí)際上我們不會(huì)通過(guò)瀏覽器直接訪問 http://...:.../api/rest_auth/login/ 這種方式來(lái)獲取 token同仆。
在前端中使用 javascript,在應(yīng)用程序中裙品,即是使用編程語(yǔ)言的網(wǎng)絡(luò)庫(kù)俗批。
它們?cè)趨?shù)上大同小異,在測(cè)試(感受如何使用)的時(shí)候市怎,還是先通過(guò)命令行工具來(lái)訪問 ?
3.2.1.1 curl 工具
http POST
"http://localhost:8000/api/rest_auth/login/"
username=<your username> password=<your password>
HTTP/1.1 200 OK
Allow: POST, OPTIONS
Content-Length: 50
Content-Type: application/json
Date: Mon, 29 Jul 2019 04:25:42 GMT
Server: WSGIServer/0.2 CPython/3.6.8
Set-Cookie: csrftoken=RRkTbmUuv6kWZtbPnJ0Yx23SIXRRe2qZV8z8ycHE2ORpU9McplBLIpmcGOLQDMcy; expires=Mon, 27 Jul 2020 04:25:42 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Set-Cookie: sessionid=m65g5ansi11jhgncmlqiaroemjgplyy8; expires=Mon, 12 Aug 2019 04:25:42 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN
{
"key": "b20...380"
}
$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
3.2.2 使用賬號(hào)的 token 訪問 model(REST API)
3.2.2.1 curl
即:
$ curl -X GET <url> -H 'Authorization: Token <上文POST之后獲得的key值>'
1
3.2.2.2 HTTPie
HTTPie 使用 token GET 數(shù)據(jù):
$ http GET
"http://localhost:8000/api/snippet/"
"Authorization: Token b20...380"
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 696
Content-Type: application/json
Date: Mon, 29 Jul 2019 04:35:30 GMT
Server: WSGIServer/0.2 CPython/3.6.8
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN
[
{
"code": "print('hello world')",
"id": 1,
"language": "python",
"linenos": false,
"style": "friendly",
"title": "Hello World of Python"
}
]
$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
HTTPie 使用 token POST 數(shù)據(jù):
$ http POST
"http://localhost:8000/api/snippet/"
'Authorization: Token b20...380'
title='Hello World of C'
code="#include <stdio.h>\n\nint main(){\n printf("hello world\n");\n}"
language=c
HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 168
Content-Type: application/json
Date: Tue, 30 Jul 2019 01:43:36 GMT
Server: WSGIServer/0.2 CPython/3.6.8
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN
{
"code": "#include <stdio.h>\n\nint main(){\n printf("hello world\n");\n}"
"id": 3,
"language": "c",
"linenos": false,
"style": "friendly",
"title": "Hello World of C"
}
$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
DELETE 數(shù)據(jù)同理岁忘,只需要將 ‘GET’ 換成 ‘DELETE’, 同時(shí)根據(jù)原本定義好的 REST API区匠,需要將 url 具體到 <int:pk> 即可(.../api/sinppet/1/)
3.2.2.3 POSTman 軟件
注意格式: Authorization : Token <the value>;
token 和 value 中間有空格
3.2.2.4 基于 requests 庫(kù)的 Python 代碼
上面分別演示了使用 curl, httpie 命令行工具和 POSTman 桌面 GUI 工具通過(guò) token 訪問 rest api干像。
現(xiàn)在落實(shí)到代碼中 ?
獲取 token:
import json
import requests
r = requests.post("http://<domain>:<port>/api/rest_auth/login/",
data={'username': '<username>', 'password': '<password>'})
if r.status_code == 200:
token = json.loads(r.text)['key']
else:
raise RuntimeError(r.text)
1
2
3
4
5
6
7
8
9
10
使用 token 訪問數(shù)據(jù):
r = requests.get('http://<domain>:<port>/api/snippet/',
headers={'Authorization': 'Token {}'.format(token)})
if r.status_code == 200:
print(json.loads(r.text))
else:
raise RuntimeError(r.text)
1
2
3
4
5
6
7
3.3 使用登錄后 Set 的 Cookie 訪問數(shù)據(jù)
3.3.1 登錄和 Set-Cookie
由于沒有單獨(dú)實(shí)現(xiàn) login 功能的頁(yè)面。所以這里也就直接借用 rest_auth 模塊的 login endpoint驰弄。
和前文一樣麻汰,使用 HTTPie 登錄等到的 HTTP Response 如下:
$ http POST
"http://localhost:8000/api/rest_auth/login/"
username=<your username> password=<your password>
HTTP/1.1 200 OK
Allow: POST, OPTIONS
Content-Length: 50
Content-Type: application/json
Date: Mon, 29 Jul 2019 04:25:42 GMT
Server: WSGIServer/0.2 CPython/3.6.8
Set-Cookie: csrftoken=RRk...Mcy; expires=Mon, 27 Jul 2020 04:25:42 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Set-Cookie: sessionid=m65g5ansi11jhgncmlqiaroemjgplyy8; expires=Mon, 12 Aug 2019 04:25:42 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN
{
"key": "b20...380"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
由上面結(jié)果顯然可以看出,服務(wù)器響應(yīng)了 Set-Cookie 內(nèi)容戚篙。
如果是瀏覽器的化五鲫,就會(huì)解析這個(gè) Set-Cookie 內(nèi)容,然后對(duì)于瀏覽器來(lái)說(shuō)岔擂,它就知道了和該網(wǎng)站訪問交互有了一個(gè)狀態(tài)(“登錄過(guò)”)位喂,這個(gè)狀態(tài)就是通過(guò) Cookie 內(nèi)容體現(xiàn)。也就是說(shuō)智亮,之后在瀏覽器上訪問這個(gè)網(wǎng)站的時(shí)候忆某,瀏覽器都會(huì)自動(dòng)帶上 Cookie 發(fā)送出去請(qǐng)求点待。
因?yàn)槭堑卿涍^(guò)阔蛉,也就是說(shuō)認(rèn)證過(guò)了,所以訪問數(shù)據(jù)是可以被允許的癞埠。也就是說(shuō)通過(guò) cookie 來(lái)表明自己的這個(gè)請(qǐng)求是認(rèn)證過(guò)的請(qǐng)求 - 即有了 cookie 就不需要 token状原。
那么顯然,直接 GET 某個(gè) REST API 是不含有 Cookie 的苗踪;所以這里要根據(jù)登錄后獲得 Response 中的 Set-Cookie 來(lái)手動(dòng)發(fā)送帶有 Cookie 的請(qǐng)求颠区。
以上面實(shí)例中的 Set-Cookie 內(nèi)容為例,不同的命令行工具的 Cookie 使用方式如下?
3.3.2 使用 Cookie 訪問數(shù)據(jù)
注意上面的 HTTP Response 中有兩個(gè) Set-Cookie 對(duì)應(yīng)著兩個(gè)核心的內(nèi)容:一個(gè)是 csrftoken通铲,一個(gè)是 sessionid毕莱。
csrftoken
在提交表單時(shí)使用(創(chuàng)建、修改、更新和刪除)朋截,這是為了防止跨域訪問蛹稍。
sessionid
翻譯過(guò)來(lái)就時(shí)“會(huì)話 ID”,所以服務(wù)器判斷當(dāng)前請(qǐng)求對(duì)應(yīng)的用戶部服,和這個(gè)用戶是否登錄過(guò)依賴的就是這個(gè) cookie 值唆姐。
如果只是 GET 數(shù)據(jù),那么 cookie 中只需要這個(gè)內(nèi)容即可廓八,不過(guò)為了簡(jiǎn)單起見奉芦,還是全部都一塊帶上好了。
3.3.2.1 HTTPie
$ http GET
"http://localhost:8000/api/snippet/"
'Cookie: csrftoken=RRk...Mcy;sessionid=m65g5ansi11jhgncmlqiaroemjgplyy8'
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 696
Content-Type: application/json
Date: Mon, 29 Jul 2019 04:25:34 GMT
Server: WSGIServer/0.2 CPython/3.6.8
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN
[
{
"code": "print('hello world')",
"id": 1,
"language": "python",
"linenos": false,
"style": "friendly",
"title": "Hello World of Python"
}
]
$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
在 HTTPie 文檔 ? 中對(duì)于 Cookie 的使用有著不錯(cuò)的描述:
Cookies
HTTP clients send cookies to the server as regular HTTP headers. That means, HTTPie does not offer any special syntax for specifying cookies — the usual Header:Value notation is used:
Send a single cookie:
$ http example.org Cookie:sessionid=foo
GET / HTTP/1.1
Accept: /
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: sessionid=foo
Host: example.org
User-Agent: HTTPie/0.9.9
1
2
3
4
5
6
7
Send multiple cookies (note the header is quoted to prevent the shell from interpreting the ;):
$ http example.org 'Cookie:sessionid=foo;another-cookie=bar'
GET / HTTP/1.1
Accept: /
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: sessionid=foo;another-cookie=bar
Host: example.org
User-Agent: HTTPie/0.9.9
1
2
3
4
5
6
7
If you often deal with cookies in your requests, then chances are you’d appreciate the sessions feature.
3.3.2.2 Curl
curl -X GET
-b 'csrftoken=RRk...Mcy;sessionid=datfyeyowug9hktb3l81ilwychlw58v3'
"http://localhost:8000/api/snippet/"
[{"id":1,"title":"Hello World of Python","code":"print('hello world')","linenos":false,"language":"python","style":"friendly"}]
1
2
3
4
5
使用 -b 或 --cookie 指定 Cookie(來(lái)源可以是文件或字符串)剧蹂,使用 ; 分隔/連接多個(gè) cookie声功。
當(dāng)然,使用 Curl 格式顯然沒有 HTTPie 美觀宠叼。不過(guò) Curl 仍然是一個(gè)值得了解的命令行工具减噪。
延伸
使用 rest_auth 相當(dāng)了簡(jiǎn)化了我們手動(dòng)去編寫代碼實(shí)現(xiàn) token 驗(yàn)證的相關(guān)邏輯。
但是如果想要從代碼層面詳細(xì)了解 token车吹,或者說(shuō)自己實(shí)現(xiàn)一份和 rest_auth 相近功能的東西筹裕,這里有幾篇重要的參考文章:
How to Implement Token Authentication using Django REST Framework ?
Django REST framework 的TokenAuth認(rèn)證及外鍵Serializer基本實(shí)現(xiàn) ?
Django REST Framework Doc – 認(rèn)證 ?
Reference
The Ultimate Tutorial for Django REST Framework: Login and Authentication (Part 2) ?
django rest auth Doc > Installation ?
————————————————
版權(quán)聲明:本文為CSDN博主「RDpWTeHM」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議窄驹,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明朝卒。
原文鏈接:https://blog.csdn.net/qq_29757283/article/details/86539882