0

我正在使用 flask-jwt-extended 来保护使用 JWT cookie 的 rest api。

我发现当

app.config['JWT_COOKIE_CSRF_PROTECT'] = True

对受保护端点的 POST 请求不起作用(而 GET 可以)。

这是我的设置。

#app.py
app = flask.Flask(__name__)

# Configure application to store JWTs in cookies
app.config['JWT_TOKEN_LOCATION'] = ['cookies']

# Only allow JWT cookies to be sent over https. In production, this
# should likely be True
app.config['JWT_COOKIE_SECURE'] = False

app.config['JWT_ACCESS_COOKIE_PATH'] = '/api/'
app.config['JWT_REFRESH_COOKIE_PATH'] = '/api/refresh'

app.config['JWT_COOKIE_CSRF_PROTECT'] = True
app.config['JWT_SESSION_COOKIE'] = False


app.config["DEBUG"] = True
app.config["JWT_SECRET_KEY"] = "123456" 

jwt = JWTManager(app)


@app.route("/api/test_protected", methods=["GET", "POST"])
@jwt_required
def test_protected():
    print("test protected ok", get_jwt_identity())
    return jsonify(success=True)

获取请求有效

Request URL: http://test.localhsl.com:8080/api/test_protected
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8080
Referrer Policy: no-referrer-when-downgrade
connection: keep-alive
content-length: 22
content-type: application/json
date: Tue, 04 Aug 2020 15:48:30 GMT
server: Werkzeug/1.0.1 Python/3.7.7
X-Powered-By: Express
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: access_token_cookie=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1OTY1NTYwNjEsIm5iZiI6MTU5NjU1NjA2MSwianRpIjoiZmJiZTM4YmYtZTMzYy00OGViLWJiZGItNmVjOThiZGMwNDVlIiwiZXhwIjoxNTk2NTU2OTYxLCJpZGVudGl0eSI6ImJyb21AcHJvdG9ubWFpbC5jb20iLCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MiLCJjc3JmIjoiMDY1YTdkNzEtYzlhZS00ZTY5LWJlMDYtYTRiYzZiNDlhODUyIn0.mfgjgXjHKibjO-HPtbdcWkXsFW5XavlxarJ0Bx64GWk; csrf_access_token=065a7d71-c9ae-4e69-be06-a4bc6b49a852; csrf_refresh_token=4669a26e-b39e-46ce-a7a3-4ac9a8d295cb
Host: test.localhsl.com:8080
Referer: http://test.localhsl.com:8080/projects
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36

但发布请求失败

Request URL: http://test.localhsl.com:8080/api/test_protected
Request Method: POST
Status Code: 401 UNAUTHORIZED
Remote Address: 127.0.0.1:8080
Referrer Policy: no-referrer-when-downgrade
connection: keep-alive
content-length: 34
content-type: application/json
date: Tue, 04 Aug 2020 15:49:48 GMT
server: Werkzeug/1.0.1 Python/3.7.7
X-Powered-By: Express
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 0
Cookie: access_token_cookie=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1OTY1NTYxODEsIm5iZiI6MTU5NjU1NjE4MSwianRpIjoiMmUzMTVhMzItY2JmOS00MzJmLWI2MGUtYTYxMjU5Yzc2YTBkIiwiZXhwIjoxNTk2NTU3MDgxLCJpZGVudGl0eSI6ImJyb21AcHJvdG9ubWFpbC5jb20iLCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MiLCJjc3JmIjoiNTMwZmQ4OGItYTYxMS00NDI2LTk3NzQtM2Q0MWNhZWRhZmQzIn0.8EqCsPSEIVsE876dBz26cHhXz-v2d2vfwyPMNo2lsng; csrf_access_token=530fd88b-a611-4426-9774-3d41caedafd3; csrf_refresh_token=9b1e5ab7-bc62-4a5d-976c-1a14a82b7cb3
Host: test.localhsl.com:8080
Origin: http://test.localhsl.com:8080
Referer: http://test.localhsl.com:8080/projects
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36

但是,如果我设置

app.config['JWT_COOKIE_CSRF_PROTECT'] = False

POST 和 GET 到受保护的端点都可以工作。

知道为什么会这样吗?

4

1 回答 1

0

您需要在您的发布请求中手动发送双重提交令牌,以保护您的应用在使用 cookie 时免受 csrf 攻击。有关详细信息,请参阅文档:https ://flask-jwt-extended.readthedocs.io/en/stable/tokens_in_cookies/

于 2020-08-05T01:52:29.660 回答