Blawxをインターネットに公開した際に発生するエラー
解決済み
修正済みのbranch: https://github.com/Syuparn/blawx/tree/fix-auth
これをdocker buildすればインターネット上でも動作します
※実運用には別途セキュリティ設定が必要
修正点
1. CSRF_TRUSTED_ORIGINS を設定可能にする
https://github.com/Syuparn/blawx/commit/a839d28313888d8a9b41ce8ad5c87f7af48e500d
現状は設定が無いため、localhost以外のIPアドレスで起動するとブラウザ側のCSRF検証が失敗、403エラーが発生しログインができない
→コンテナの環境変数から読み込めるよう設定追加
CSRF_TRUSTED_ORIGINS={デプロイしたURL}を設定する
例:GCPの場合の設定方法: https://cloud.google.com/run/docs/configuring/services/environment-variables?hl=ja
2. Blocklyのバージョンを固定
https://github.com/Syuparn/blawx/commit/a6404445eb61fe90f6946c3c8a9fe869f82de32c
DockerfileではBlocklyのバージョンが指定されていないため、今ビルドすると当時のイメージよりも新しいバージョンがインストールされる
Blawxでは古いBlocklyでしか動作しない関数を使用しているためブロックの補完、保存が正常動作しなくなる
→npmでバージョンを明示するよう修正
本家にもPR出した: https://github.com/Lexpedite/blawx/pull/588
ログイン画面で403エラー
Cloud Runに公式イメージをデプロイした際、login or registerしようとするとエラーが発生
code:_
Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
Origin checking failed - https://{デプロイしたURL} does not match any trusted origins.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django’s CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function passes a request to the template’s render method.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
The form has a valid CSRF token. After logging in in another browser tab or hitting the back button after a login, you may need to reload the page with the form, because the token is rotated after a login.
You’re seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
https://docs.djangoproject.com/en/4.2/ref/csrf/
formにcsrf_token は入っている https://github.com/Lexpedite/blawx/blob/6a717b1920e21236536dcd4877e832cdb100f691/blawx/templates/registration/register.html#L10
そもそも CORS_ALLOW_ALL_ORIGINS = True
https://pypi.org/project/django-cors-headers/
https://github.com/Lexpedite/blawx/blob/6a717b1920e21236536dcd4877e832cdb100f691/blawx/settings.py#L70
導入されたタイミング: django-cors-headers 3.5.0 Rename CORS_ORIGIN_ALLOW_ALL to CORS_ALLOW_ALL_ORIGINS (#563) · adamchainz/django-cors-headers@e4a6e0a
バージョンも問題なかった
code:_
$ docker run -it -p 8000:8000 lexpedite/blawx:latest sh
# pip freeze | grep django-cors-headers
django-cors-headers==4.2.0
このPRで追加されているが、やはりデフォルトでは土のホストでも許可する想定に見える
https://github.com/Lexpedite/blawx/pull/556/files#diff-09b140a43ebfdd8dbec31ce72cafffd15164d2860fd390692a030bcb932b54a0R89
CSRF_TRUSTED_ORIGINSも必要に見える
https://github.com/Syuparn/blawx/commit/ba0b730d3414c467864af68bea15f5fc09345622#diff-d9861635612d4487136f3d9d792bb5e5a7345685deacd7c40e870ebb34e41c9fR166
(↑のURLは検証後破棄したのでもう無効です(一応))
https://scrapbox.io/files/6794cc2e44d21f5f0b1aff5d.png
以下で解消した
https://github.com/Syuparn/blawx/commit/a839d28313888d8a9b41ce8ad5c87f7af48e500d#diff-d9861635612d4487136f3d9d792bb5e5a7345685deacd7c40e870ebb34e41c9fR76
code:py
CSRF_TRUSTED_ORIGINS = []
if 'CSRF_TRUSTED_ORIGINS' in os.environ:
CSRF_TRUSTED_ORIGINS.append(os.environ.get('CSRF_TRUSTED_ORIGINS'))
コンテナ起動時に環境変数を指定
CSRF_TRUSTED_ORIGINS={デプロイしたURL}
GCPの場合の設定方法: https://cloud.google.com/run/docs/configuring/services/environment-variables?hl=ja
公式のドキュメントにもあるように、その他のセキュリティ設定も必要になりそう
code:_
Steps for deploying will include at a minimum:
* changing the server_name settings in the settings.py file
* changing the DEBUG setting in the settings.py file
* adding configurations for secure CRSF and Cookies in the settings.py file
* configuring nginx or another proxy server to directly serve static files
* configuring TLS
* replacing the manage.py runserver with a production WSGI web server
* replacing the CORS configuration (which is open by default) with a whitelist
https://github.com/Lexpedite/blawx/blob/main/INSTALL.md
ブロックが動作しない
考えられる原因:
localhostでしか動かないAPIリクエストがまぎれている?
コードエディタの挙動
objects/known objects等自分で定義したブロックのタブを開く際に以下へリクエスト
localhost, じゃんけんの場合
http://localhost:8000/syuparn/rock-paper-scissors-act/all/get/
path: /:user/:project/all/get/
呼び出されるハンドラ
code:py
@api_view('GET')
@authentication_classes(SessionAuthentication)
@permission_classes(IsAuthenticatedOrReadOnly)
def get_all_code(request,user,rule):
owner = User.objects.get(username=user)
workspaces = Workspace.objects.filter(ruledoc=RuleDoc.objects.get(rule_slug=rule,owner=owner))
output = []
for w in workspaces:
if request.user.has_perm('blawx.view_workspace',w):
output.append({"name": w.workspace_name, "xml_content": w.xml_content})
else:
return HttpResponseForbidden()
return Response(output)
エラーの発生条件
no categories definedのメニューを開く
以下のエラー発生
https://scrapbox.io/files/67bab611575b3e62fda8f352.png
consoleに発生したエラーメッセージ
code:_
Uncaught Error: sCASP generator does not know how to generate code for block type "unattributed_fact".
at Object.blockToCode (generator.ts:259:13)
at Object.workspaceToCode (generator.ts:159:23)
at liveCode (blawx2scasp.js:3:20)
at WorkspaceSvg$$module$build$src$core$workspace_svg.fireChangeListener (workspace.ts:704:7)
at fireNow$$module$build$src$core$events$utils (utils.ts:131:49)
エラーはBlockyで出ている
https://github.com/google/blockly/blob/7e44e81e4270779f7f05e57cdb3ac6ab8e343aca/core/generator.ts#L260
Objectsを選択したらエラー発生
https://scrapbox.io/files/67baba9489d493e989317e9d.png
レスポンスをデバッグ表示する
https://scrapbox.io/files/67babaf85370174ceebdb312.png
code:_
DoesNotExist at /syuparn/foobar/all/get/
User matching query does not exist.
そもそもトップページに戻れない
https://scrapbox.io/files/67babe5825c3093a89234076.png
code:_
Page not found (404)
No User matches the given query.
Request Method: GET
Request URL: http://{デプロイURL}/syuparn/foobar/code/
Raised by: blawx.views.BlawxView
Using the URLconf defined in blawx.urls, Django tried these URL patterns, in this order:
accounts/
accounts/login name='login'
accounts/logout name='logout'
accounts/password_change name='password_change'
accounts/password_change_done name='password_change_done'
name='ruledocs'
docs/<path:pk>/ name='docs_page'
import/ name='import'
load_example/<slug:example_name>/ name='load'
<user>/<slug:rule>/ name='ruledoc'
<user>/<slug:rule>/rule/<slug:section_name>/ name='ruledoc_text'
<user>/<slug:rule>/edit/ name='ruledoc_edit'
<user>/<slug:rule>/code/ name='code'
The current path, syuparn/foobar/code/, matched the last one.
You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
アカウントを作り直すと入れた
エラーはでなくなったがブロックの表示はされないまま
https://scrapbox.io/files/67bac02f50f18deeaf2a364e.png
https://scrapbox.io/files/67bac04f61777655cfc8a7cf.png
Saveを押しても保存できない
/update がリクエストされない
ここ?違うかも https://github.com/Lexpedite/blawx/blob/6a717b1920e21236536dcd4877e832cdb100f691/blawx/templates/blawx/blawxtest_form.html#L16
フロントエンドでレンダリングされた生のHTML
code:html
<button class="btn mb-1 me-2 btn-sm btn-primary " onclick="updateWorkspace()">
<i class="bi bi-save pe-2"></i>Save
</button>
実装
code:js
var updateWorkspace
updateWorkspace = function() {
var payload = {}
var main_xml = Blockly.Xml.workspaceToDom(demoWorkspace);
// Output the current workspace to a variable
payload.xml_content = Blockly.Xml.domToText(main_xml);
// Output the current encoding to a variable
payload.scasp_encoding = sCASP.workspaceToCode(demoWorkspace);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "../" + current_section + "/update/", true);
xhttp.setRequestHeader('Content-type', 'application/json');
xhttp.setRequestHeader('X-CSRFToken', csrftoken);
xhttp.onreadystatechange = function() {
console.log("Saved")
};
console.log("Saving")
xhttp.send(body=JSON.stringify(payload));
Blockly.hideChaff();
}
consoleで別のエラーが起きていた
code:_
Uncaught Error: sCASP generator does not know how to generate code for block type "unattributed_fact".
at Object.blockToCode (generator.ts:259:13)
at Object.workspaceToCode (generator.ts:159:23)
at updateWorkspace (buttons.js:24:36)
at HTMLButtonElement.onclick (code/:540:91)
オリジナルのイメージの場合(比較)
バージョンが固定されていないためdeprecated要素が最新版で動かなくなっている?
code:_
block generator functions on CodeGenerator objects was deprecated in 10.0 and will be deleted in 11.0.
Use the .forBlockblockType dictionary instead.
npmで入れているのでpipではない
https://github.com/Lexpedite/blawx/blob/6a717b1920e21236536dcd4877e832cdb100f691/Dockerfile#L57
オリジナル
code:_
root@e4d8dc92669f:/app/blawx# npm list
app@ /app
├── blockly@10.1.3
├── bootstrap-icons@1.11.1
├── bootstrap@5.3.2
└── jquery@3.7.1
パッチ
code:_
root@2fc58e0fb5fd:/app/blawx# npm list
app@ /app
├── blockly@11.2.1
├── bootstrap-icons@1.11.3
├── bootstrap@5.3.3
└── jquery@3.7.1
いったんは10.1.3で固定すれば回避できそう
deprecatedに対処するのは改めて行う
固定したら直った!!!
https://scrapbox.io/files/67bbf6266468f6d3bd7fbd63.png
修正したDockerfile
code:Dockerfile
# NOTE: currently Blawx blocks works only blockly < 11.0
# update to the latest version after the deprecation warning below is resolved
#
# block generator functions on CodeGenerator objects was deprecated in 10.0 and will be deleted in 11.0. Use the .forBlockblockType dictionary instead.
RUN npm install blockly@10.1.3
#blawx