{"id":429,"date":"2024-01-27T08:29:12","date_gmt":"2024-01-26T23:29:12","guid":{"rendered":"https:\/\/www.kd2.jp\/memo3\/?p=429"},"modified":"2024-01-30T05:43:40","modified_gmt":"2024-01-29T20:43:40","slug":"react-jwt-2","status":"publish","type":"post","link":"https:\/\/www.kd2.jp\/memo3\/?p=429","title":{"rendered":"React + JWT p2"},"content":{"rendered":"<p><a href=\"https:\/\/fastapi.tiangolo.com\/tutorial\/security\/simple-oauth2\/\"><br \/>\nFastAPI<br \/>\nSimple OAuth2 with Password and Bearer<br \/>\n<\/a>\u306b\u3064\u306a\u3052\u3066\u30c6\u30b9\u30c8\u3059\u308b\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>index.tsx<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text\/javascript&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:true,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">import React from 'react';\r\nimport ReactDOM from 'react-dom\/client';\r\nimport '.\/index.css';\r\nimport UsersMe from '.\/UsersMe';\r\nimport reportWebVitals from '.\/reportWebVitals';\r\n\r\nconst root = ReactDOM.createRoot(\r\n  document.getElementById('root') as HTMLElement\r\n);\r\nroot.render(\r\n  &lt;React.StrictMode&gt;\r\n    &lt;UsersMe \/&gt;\r\n  &lt;\/React.StrictMode&gt;\r\n);\r\n\r\n\/\/ If you want to start measuring performance in your app, pass a function\r\n\/\/ to log results (for example: reportWebVitals(console.log))\r\n\/\/ or send to an analytics endpoint. Learn more: https:\/\/bit.ly\/CRA-vitals\r\nreportWebVitals();\r\n<\/pre>\n<\/div>\n<p>Login.tsx<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text\/javascript&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">import React, { useState } from 'react';\r\nimport UsersMe from '.\/UsersMe';\r\n\r\nconst Login = () =&gt; {\r\n    const [user, setUser] = useState({username: '', password: ''});\r\n    const [isAuthenticated, setAuth] = useState(false);\r\n\r\n    const handleChange = (event : any) =&gt; {\r\n        setUser({...user, [event.target.name] : event.target.value})\r\n    }\r\n\r\n    const login = () =&gt; {\r\n        console.log(JSON.stringify(user));\r\n        fetch(\"http:\/\/127.0.0.1:8000\/token\", \r\n        {\r\n            method : \"POST\",\r\n            headers : {\r\n                'Content-Type' : 'application\/x-www-form-urlencoded'\r\n            },\r\n            body: `username=${user.username}&amp;password=${user.password}`\r\n        })\r\n        .then(response =&gt; response.json())\r\n        .then(responseJSON =&gt; {\r\n            const access_token = responseJSON.access_token;\r\n            if (access_token !== null) {\r\n                sessionStorage.setItem(\"access_token\", access_token);\r\n                setAuth(true);\r\n            }\r\n        })\r\n        .catch(error =&gt; {\r\n            console.error(error);\r\n        })\r\n    }\r\n\r\n    if (isAuthenticated) {\r\n        return(\r\n            &lt;div&gt;\r\n                &lt;UsersMe \/&gt;\r\n            &lt;\/div&gt;  \r\n        );\r\n    }\r\n    else {\r\n        return(\r\n            &lt;div&gt;\r\n                &lt;input type=\"text\" name=\"username\" onChange={handleChange} \/&gt;&lt;br \/&gt;\r\n                &lt;input type=\"password\" name=\"password\" onChange={handleChange} \/&gt;&lt;br \/&gt;\r\n                &lt;button onClick={login}&gt;Login&lt;\/button&gt;\r\n            &lt;\/div&gt;\r\n        );\r\n    }\r\n\r\n}\r\n\r\nexport default Login;<\/pre>\n<\/div>\n<p>UsersMe.tsx<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text\/javascript&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">import React, { useLayoutEffect, useState } from 'react';\r\nimport Login from '.\/Login';\r\nimport UsersMeItem from '.\/UsersMeItems';\r\n\r\nconst UsersMe = () =&gt; {\r\n    const [userInfo, setUserInfo] = useState(\"\");\r\n    const [isAuthenticated, setAuth] = useState(false);\r\n\r\n    useLayoutEffect(() =&gt; {\r\n        users_me();\r\n    });\r\n\r\n    const users_me = () =&gt; {\r\n        const access_token = sessionStorage.getItem(\"access_token\");\r\n        fetch(\"http:\/\/localhost:8000\/users\/me\",\r\n        {\r\n            method : \"GET\",\r\n            headers : {\r\n                'Authorization' : 'Bearer ' + access_token\r\n            },\r\n        })\r\n        .then(response =&gt; {\r\n            if (response.status === 200) {\r\n                setAuth(true);\r\n                return response.json();\r\n            }\r\n            sessionStorage.setItem(\"access_token\", \"\");\r\n            setAuth(false);\r\n            return null;\r\n        })\r\n        .then(responseJSON =&gt; {\r\n            if (responseJSON) {\r\n                setUserInfo(JSON.stringify(responseJSON));\r\n            }\r\n        })\r\n        .catch(error =&gt; {\r\n            console.error(error);\r\n        })\r\n    }\r\n\r\n    const logout = () =&gt; {\r\n        sessionStorage.setItem(\"access_token\", \"\");\r\n        setAuth(false);\r\n    }\r\n\r\n    if (isAuthenticated) {\r\n        return(\r\n            &lt;div&gt;\r\n                Me : {userInfo} \r\n                &lt;UsersMeItem \/&gt; \r\n                &lt;button onClick={logout}&gt;Logout&lt;\/button&gt;\r\n            &lt;\/div&gt;\r\n        );\r\n    }\r\n    else {\r\n        return(\r\n            &lt;div&gt;\r\n                &lt;Login \/&gt;\r\n            &lt;\/div&gt;\r\n        );\r\n    }\r\n}\r\n\r\nexport default UsersMe;<\/pre>\n<\/div>\n<p>UsersMeItems.tsx<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text\/javascript&quot;,&quot;theme&quot;:&quot;eclipse&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:false,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">import React, { useLayoutEffect, useState } from 'react';\r\n\r\nconst UsersMeItem = () =&gt; {\r\n    const [itemInfo, setItemInfo] = useState(\"\");\r\n\r\n    useLayoutEffect(() =&gt; {\r\n        users_me_item();\r\n    });\r\n\r\n    const users_me_item = () =&gt; {\r\n        const access_token = sessionStorage.getItem(\"access_token\");\r\n        fetch(\"http:\/\/localhost:8000\/users\/me\/items\",\r\n        {\r\n            method : \"GET\",\r\n            headers : {\r\n                'Authorization' : 'Bearer ' + access_token\r\n            },\r\n        })\r\n        .then(response =&gt; {\r\n            if (response.status === 200) {\r\n                return response.json();\r\n            }\r\n            return null;\r\n        })\r\n        .then(responseJSON =&gt; {\r\n            if (responseJSON) {\r\n                setItemInfo(JSON.stringify(responseJSON));\r\n            }\r\n        })\r\n        .catch(error =&gt; {\r\n            console.error(error);\r\n        })\r\n    }\r\n\r\n    return(\r\n        &lt;div&gt;\r\n            Item : {itemInfo}\r\n        &lt;\/div&gt;\r\n    );\r\n}\r\n\r\nexport default UsersMeItem;<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>FastAPI Simple OAuth2 with Password and Bearer \u306b\u3064\u306a\u3052\u3066\u30c6\u30b9\u30c8\u3059\u308b\u3002 &nbsp; index.tsx import React from &#8216;react&#8217;; import &hellip; <a class=\"more-link\" href=\"https:\/\/www.kd2.jp\/memo3\/?p=429\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"screen-reader-text\">React + JWT p2<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[17],"tags":[],"_links":{"self":[{"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=\/wp\/v2\/posts\/429"}],"collection":[{"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=429"}],"version-history":[{"count":7,"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=\/wp\/v2\/posts\/429\/revisions"}],"predecessor-version":[{"id":438,"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=\/wp\/v2\/posts\/429\/revisions\/438"}],"wp:attachment":[{"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kd2.jp\/memo3\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}