6: 2021-08-30 (月) 11:34:38 iseki |
現: 2023-04-24 (月) 00:29:00 iseki |
- | ** Hack for Moodle LTI [#w4c22429] | + | ** Hack for [[Moodle]] - [[LTI]] [#w4c22429] |
- | *** [[JupyterHub]] の Swapner での受け取り処理 [#vd91a1e1] | + | - [[Moodle+JupyterHub]] |
| + | - [[Moodle]], [[JupyterHub]] |
| + | - [[LTI]] |
| + | #br |
| + | |
| + | *** iframe を使用すると,chrome, edgeでは 405 : Method Not Allowed が返される件 [#id5b6e70] |
| + | - SameSite=Lax であるため,iframe 使用時は Moodleのホストと JupyterHub のホストが異なる場合は,cookie が送信されない. |
| + | #br |
| + | |
| + | **** JupyterHub の log [#y1916cbf] |
| + | - 返されたステータス |
| + | -- 302 POST |
| + | -- 302 GET (通常はここで 200が返る) |
| + | -- 302 GET |
| + | -- 405 GET |
| + | #br |
| + | |
| + | **** ソースコード トレース (数字はトレース順) [#oaf0a04f] |
| + | - ltiauthenticator/lti11/auth.py |
| + | -- 0. authenticate() |
| + | |
| + | - jupyterhub/handlers/base.py |
| + | -- 4. login_user() self.current_user -> None |
| + | -- 5. self.get_current_user_cookie() |
| + | -- 6. self._user_for_cookie() cookie_id-> None cookie_name=jupyterhub-hub-login |
| + | |
| + | - tornado/web.py |
| + | -- 1. _unimplemented_method() HTTPError(405) を返す |
| + | -- 2. wrapper() で 302 が返る.通常なら 200 が返るはず. |
| + | -- 3. self.current_user -> None |
| + | -- 7. get_secure_cookie() ''結局,jupyterhub-hub-login のクッキーありません.(Webブラウザから送信されていません)'' |
| + | #br |
| + | |
| + | **** Moodle ホスト上で,JupyterHub へ接続するための feserver を動かしてみる. [#a6a32ef6] |
| + | - cookie が送信されない理由について推測が正しいならば,MoodleとJupyterHubを同じホストで動かせば(若しくは動いているように見せれば),iframeは問題なく使用できるはず. |
| + | - feserver のSSLのサーバ証明書で手こずったが,Apacheで使用している証明書使用したところ上手く繋がった. |
| + | - chrome, edge でも iframe の埋め込みが問題なく動作. |
| + | - でも問題点を確認したのみで,解決にはなっていない. |
| + | |
| + | - ''問題点: Moodleと JupyterHubを別のホストで動かすと,iframe を使用した場合,chrome, edge から cookieが送信されない.''(その内 FireFoxもだよね) |
| + | #br |
| + | **** 解決方法 [#f974d825] |
| + | |
| + | c.JupyterHub.tornado_settings = { |
| + | "headers":{ "Content-Security-Policy": "frame-ancestors 'self' https://www.nsl.tuis.ac.jp" }, |
| + | "cookie_options": {"SameSite": "None", "Secure": True } |
| + | } |
| + | |
| + | c.Spawner.args = ['--NotebookApp.tornado_settings={ |
| + | "headers":{"Content-Security-Policy": "frame-ancestors \'self\' https://www.nsl.tuis.ac.jp" }, |
| + | "cookie_options": { "SameSite": "None", "Secure": True } |
| + | }' |
| + | ] |
| + | |
| + | **** 参考:DB [#vf633496] |
| + | MariaDB [moodle_db]> show columns from mdl_lti; |
| + | +-------------------------------+--------------+------+-----+---------+----------------+ |
| + | | Field | Type | Null | Key | Default | Extra | |
| + | +-------------------------------+--------------+------+-----+---------+----------------+ |
| + | | id | bigint(10) | NO | PRI | NULL | auto_increment | |
| + | | course | bigint(10) | NO | MUL | 0 | | |
| + | | name | varchar(255) | NO | | | | |
| + | | intro | longtext | YES | | NULL | | |
| + | | introformat | smallint(4) | YES | | 0 | | |
| + | | timecreated | bigint(10) | NO | | 0 | | |
| + | | timemodified | bigint(10) | NO | | 0 | | |
| + | | typeid | bigint(10) | YES | | NULL | | |
| + | | toolurl | longtext | NO | | NULL | | |
| + | | securetoolurl | longtext | YES | | NULL | | |
| + | | instructorchoicesendname | tinyint(1) | YES | | NULL | | |
| + | | instructorchoicesendemailaddr | tinyint(1) | YES | | NULL | | |
| + | | instructorchoiceallowroster | tinyint(1) | YES | | NULL | | |
| + | | instructorchoiceallowsetting | tinyint(1) | YES | | NULL | | |
| + | | instructorcustomparameters | longtext | YES | | NULL | | |
| + | | instructorchoiceacceptgrades | tinyint(1) | YES | | NULL | | |
| + | | grade | bigint(10) | NO | | 100 | | |
| + | | launchcontainer | tinyint(2) | NO | | 1 | | |
| + | | resourcekey | varchar(255) | YES | | NULL | | |
| + | | password | varchar(255) | YES | | NULL | | |
| + | | debuglaunch | tinyint(1) | NO | | 0 | | |
| + | | showtitlelaunch | tinyint(1) | NO | | 0 | | |
| + | | showdescriptionlaunch | tinyint(1) | NO | | 0 | | |
| + | | servicesalt | varchar(40) | YES | | NULL | | |
| + | | icon | longtext | YES | | NULL | | |
| + | | secureicon | longtext | YES | | NULL | | |
| + | +-------------------------------+--------------+------+-----+---------+----------------+ |
| + | |
| + | <option value="1" selected="">デフォルト</option> |
| + | <option value="2">埋め込み</option> |
| + | <option value="3">埋め込み (ブロックなし)</option> |
| + | <option value="5">既存のウィンドウ</option> |
| + | <option value="4">新しいウィンドウ</option> |
| + | |
| + | *** [[JupyterHub]] の Swapner での LTI 情報の受け取り処理 [#vd91a1e1] |
| - jupyterhub_config.py | | - jupyterhub_config.py |
| import os | | import os |
| - Moodleの外部ツールの設定で,「一般」の「さらに表示する」でカスタムパラメータを指定すると,JupyterHub に任意のパラメータを送れる. | | - Moodleの外部ツールの設定で,「一般」の「さらに表示する」でカスタムパラメータを指定すると,JupyterHub に任意のパラメータを送れる. |
| -- ''XXX=ZZZ'' と入力すると,上記方法で ''{'costom_xxx': 'ZZZ'}'' として受け取れる(キーは小文字化される). | | -- ''XXX=ZZZ'' と入力すると,上記方法で ''{'costom_xxx': 'ZZZ'}'' として受け取れる(キーは小文字化される). |
- | -- # - などの特殊文字は ''_'' になる. | + | -- # - などの特殊文字は ''_'' になる.''snake_case'' と言うらしい. |
| | | |
| | | |
| - 一般的に認証モジュールが引数として受け取る値 | | - 一般的に認証モジュールが引数として受け取る値 |
| { | | { |
- | 'oauth_version': '1.0', | + | 'user_id': '2', |
- | 'oauth_nonce': '58d68cc3fdedf30d9eeb968e0a057999', | + | 'lis_person_sourcedid': '', |
- | 'oauth_timestamp': '1626225398', | + | 'roles': 'Instructor,urn:lti:sysrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Administrator', |
- | 'oauth_consumer_key': 'b18e82ec683724743236fade71350720029a29144a585c66f6741d8e9c6e0d83', | + | 'context_id': '98', |
- | 'user_id': '160', | + | 'context_label': 'JupyterHub-devel', |
- | 'lis_person_sourcedid': '', | + | 'context_title': 'JupyterHub 開発', |
- | 'roles': 'Learner', | + | 'resource_link_title': 'JupyterHub', |
- | 'context_id': '98', | + | 'resource_link_description': '', |
- | 'context_label': 'TEST2_1', | + | 'resource_link_id': '11', |
- | 'context_title': 'TEST2 コピー 1', | + | 'context_type': 'CourseSection', |
- | 'resource_link_title': 'JupyterHub', | + | 'lis_course_section_sourcedid': '', |
- | 'resource_link_description': '', | + | 'lis_result_sourcedid': '{ |
- | 'resource_link_id': '10', | + | "data":{ |
- | 'context_type': 'CourseSection', | + | "instanceid":"11", |
- | 'lis_course_section_sourcedid': '', | + | "userid":"2", |
- | 'lis_result_sourcedid': '{ | + | "typeid":"2", |
- | "data":{ | + | "launchid":1442412989 |
- | "instanceid":"10", | + | }, |
- | "userid":"160", | + | "hash":"a526aa576887b4dc19c16107e9ac7b0dbc92f852e23f044d55356ba83f3b7037" |
- | "typeid":"2", | + | }', |
- | "launchid":1197426197 | + | 'lis_outcome_service_url': 'https://el.mml.tuis.ac.jp/moodle/mod/lti/service.php', |
- | }, | + | 'lis_person_name_given': 'Admin', |
- | "hash":"77b06a98a08b45f95dc420e2453bd64fdbe02379ed010b53a501e228c03b2005" | + | 'lis_person_name_family': '管理ユーザ', |
- | }', | + | 'lis_person_name_full': 'Admin 管理ユーザ', |
- | 'lis_outcome_service_url': 'https://el.mml.tuis.ac.jp/moodle/mod/lti/service.php', | + | 'ext_user_username': 'admin', |
- | 'lis_person_name_given': 'bob', | + | 'lis_person_contact_email_primary': 'fumi.hax@gmail.com', |
- | 'lis_person_name_family': 'テストユーザ', | + | 'launch_presentation_locale': 'ja', |
- | 'lis_person_name_full': 'bob テストユ ーザ', | + | 'ext_lms': 'moodle-2', |
- | 'ext_user_username': 'bob', | + | 'tool_consumer_info_product_family_code': 'moodle', |
- | 'lis_person_contact_email_primary': 'bob@solar-system.tuis.ac.jp', | + | 'tool_consumer_info_version': '2020110902', |
- | 'launch_presentation_locale': 'ja', | + | 'lti_version': 'LTI-1p0', |
- | 'ext_lms': 'moodle-2', | + | 'lti_message_type': 'basic-lti-launch-request', |
- | 'tool_consumer_info_product_family_code': 'moodle', | + | 'tool_consumer_instance_guid': '5384b0f81508b987c188b1985f5cd4e0', |
- | 'tool_consumer_info_version': '2020110902', | + | 'tool_consumer_instance_name': 'EL MML', |
- | 'oauth_callback': 'about:blank', | + | 'tool_consumer_instance_description': |
- | 'lti_version': 'LTI-1p0', | + | 'e-Learning of MML', |
- | 'lti_message_type': 'basic-lti-launch-request', | + | 'custom_mdl_user': '*', |
- | 'tool_consumer_instance_guid': '5384b0f81508b987c188b1985f5cd4e0', | + | 'custom_mdl_teacher': 'iseki, admin', |
- | 'tool_consumer_instance_name': 'EL MML', | + | 'custom_mdl_image': 'jupyterhub/singleuser-mdl2 : latest', |
- | 'tool_consumer_instance_description': 'e-Learning of MML', | + | 'custom_mdl_suburl': '', |
- | 'launch_presentation_document_target': 'window', | + | 'custom_mdl_sessioninfo': '3,11', |
- | 'launch_presentation_return_url': 'https://el.mml.tuis.ac.jp/moodle/mod/lti/return.php?course=98&launch_container=4&instanceid=10&sesskey=DSnzLC42wK', | + | 'custom_mdl_vol_zzzz': '課題2', |
- | 'oauth_signature_method': 'HMAC-SHA1', | + | 'custom_mdl_vol_iseki': 'へへへ', |
- | 'oauth_signature': 't+ctcGhvev5hDh/Tz21NOYFBw8s=' | + | 'custom_mdl_vol_jogrid': 'へへへ', |
| + | 'custom_mdl_vol_': 'えええええええ', |
| + | 'custom_mdl_vol_hhhhhggjjj': 'あああ', |
| + | 'custom_mdl_vol_xxxx': 'いいいい', |
| + | 'custom_mdl_sub_xxxx': '課題提出場所', |
| + | 'custom_md_teacher': 'iseki', |
| + | 'custom_ssss': '777', |
| + | 'custom_zzzz': '', |
| + | 'launch_presentation_document_target': 'window', |
| + | 'launch_presentation_return_url': 'https://el.mml.tuis.ac.jp/moodle/mod/lti/return.php?course=98&launch_container=4&instanceid=11&sesskey=6wL3CYeL7Z' |
| } | | } |
| + | #br |
| + | ** Moodle DB [#sab902e6] |
| + | *** LTIの typeid (External Tool 情報) を格納するテーブル [#d76ec06b] |
| + | MariaDB [moodle_db]> select id, name,baseurl,tooldomain,state,course,clientid from mdl_lti_types ; |
| + | +----+------------------+----------------------------------------------------+-----------------------------+-------+--------+-----------------+ |
| + | | id | name | baseurl | tooldomain | state | course | clientid | |
| + | +----+------------------+----------------------------------------------------+-----------------------------+-------+--------+-----------------+ |
| + | | 3 | antares:443 | https://antares.nsl.tuis.ac.jp/hub/lti/launch | antares.nsl.tuis.ac.jp | 1 | 1 | Oh9MyHxutcfbvhA | |
| + | | 4 | GITLAB:FE 8100 | https://gitlab.nsl.tuis.ac.jp:8100/hub/lti/launch | gitlab.nsl.tuis.ac.jp:8100 | 1 | 1 | NULL | |
| + | | 10 | procyon:443 | https://jupyterhub.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub.nsl.tuis.ac.jp | 1 | 1 | NULL | |
| + | | 12 | JupyterHub00:443 | https://jupyterhub00.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub00.nsl.tuis.ac.jp | 1 | 1 | NULL | |
| + | | 13 | JupyterHub01:443 | https://jupyterhub01.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub01.nsl.tuis.ac.jp | 1 | 1 | NULL | |
| + | | 14 | JupyterHub02:443 | https://jupyterhub02.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub02.nsl.tuis.ac.jp | 1 | 1 | NULL | |
| + | | 15 | JupyterHub03:443 | https://jupyterhub03.nsl.tuis.ac.jp/hub/lti/launch | jupyterhub03.nsl.tuis.ac.jp | 1 | 1 | NULL | |
| + | | 19 | antares:8000 | https://antares.nsl.tuis.ac.jp:8000/hub/lti/launch | antares.nsl.tuis.ac.jp:8000 | 1 | 1 | NULL | |
| + | | 20 | aldebaran:443 | https://aldebaran.nsl.tuis.ac.jp/hub/lti/launch | aldebaran.nsl.tuis.ac.jp | 1 | 1 | NULL | |
| + | +----+------------------+----------------------------------------------------+-----------------------------+-------+--------+-----------------+ |
| + | - tooldomain は baseurl から抽出したようだ. |
| + | - clientid ??? |
| #br | | #br |