{"id":11811,"date":"2024-03-24T23:15:12","date_gmt":"2024-03-24T14:15:12","guid":{"rendered":"https:\/\/www.webcyou.com\/?p=11811"},"modified":"2024-03-24T23:15:13","modified_gmt":"2024-03-24T14:15:13","slug":"rust-actix-web-mongo-%e3%83%a6%e3%83%bc%e3%82%b6%e3%83%bc%e7%99%bb%e9%8c%b2-jwt%e8%aa%8d%e8%a8%bc","status":"publish","type":"post","link":"https:\/\/www.webcyou.com\/?p=11811","title":{"rendered":"Rust &#8211; Actix Web mongo \u30e6\u30fc\u30b6\u30fc\u767b\u9332 JWT\u8a8d\u8a3c"},"content":{"rendered":"\n\n\n<p>\u3069\u3082\u3067\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306f\u524d\u56de\u306e\u300c<strong><a href=\"https:\/\/www.webcyou.com\/?p=11748\">Rust \u2013 Actix Web JWT \u8a8d\u8a3c\u8a8d\u53ef API\u306e\u4f5c\u6210<\/a><\/strong>\u300d\u306e\u7d9a\u304d\u3068\u306a\u308a\u3001\u307e\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u3057\u3066MongoDB\u3092\u7528\u3044\u308b\u5f62\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u74b0\u5883\u8a2d\u5b9a\u306a\u3069\u306b\u95a2\u3057\u3066\u306f\u3001\u4ee5\u524d\u306e\u8a18\u4e8b\u300c<strong><a href=\"https:\/\/www.webcyou.com\/?p=11736\">Rust \u2013 Actix Web \u00d7 MongoDB\u74b0\u5883\u3092\u30b5\u30af\u30c3\u3068\u8d77\u52d5<\/a><\/strong>\u300d<\/p>\n<p>\u306a\u3069\u3092\u53c2\u7167\u3057\u3066\u3044\u305f\u3060\u3051\u308c\u3070\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u69cb\u6210\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n<p><!-- notionvc: 151c271d-c785-4c8e-bf31-9ca66bbf9dca --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">jwt_auth_user\/src\/\n\u251c\u2500\u2500 api\n\u2502   \u251c\u2500\u2500 mod.rs\n\u2502   \u251c\u2500\u2500 token.rs\n\u2502   \u2514\u2500\u2500 user.rs\n\u251c\u2500\u2500 constants.rs\n\u251c\u2500\u2500 error.rs\n\u251c\u2500\u2500 main.rs\n\u251c\u2500\u2500 model\n\u2502   \u251c\u2500\u2500 mod.rs\n\u2502   \u251c\u2500\u2500 response.rs\n\u2502   \u251c\u2500\u2500 token.rs\n\u2502   \u2514\u2500\u2500 user.rs\n\u251c\u2500\u2500 repository\n\u2502   \u251c\u2500\u2500 mdb.rs\n\u2502   \u2514\u2500\u2500 mod.rs\n\u2514\u2500\u2500 utils\n    \u251c\u2500\u2500 mod.rs\n    \u2514\u2500\u2500 token.rs<\/pre>\n<p>\u524d\u56de\u306e\u3082\u306e\u3092\u4f7f\u3044\u307e\u308f\u3057\u305f\u3046\u3048\u3001user\u3092\u8ffd\u52a0\u3001DB\u64cd\u4f5c\u3092\u884c\u3046\u30ec\u30a4\u30e4\u30fc\u3068\u3057\u3066\u3001repository\u304c\u8ffd\u52a0\u3055\u308c\u305f\u5f62\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>Actix-web\u516c\u5f0f\u30b5\u30a4\u30c8\u306e\u30b5\u30f3\u30d7\u30eb\u306e\u300c<strong><a href=\"https:\/\/github.com\/actix\/examples\/tree\/master\/databases\/mongodb\">MongoDB<\/a><\/strong>\u300d\u3088\u308a\u3001\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u3092\u884c\u3063\u305f\u5f62\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>repository\u30ec\u30a4\u30e4\u30fc\u3092\u8ffd\u52a0\u3057\u305fMongoDB\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30bd\u30fc\u30b9<\/p>\n<p><a href=\"https:\/\/github.com\/rust-game-samples\/actix_web_sample\/tree\/main\/mongodb\/src\">https:\/\/github.com\/rust-game-samples\/actix_web_sample\/tree\/main\/mongodb\/src<\/a><\/p>\n<p>\u3053\u3061\u3089\u3068\u3001\u524d\u56de\u306e\u3082\u306e\u3092\u30ac\u30c3\u30c1\u30e3\u30f3\u30b3\u3057\u307e\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306e\u4f5c\u6210\u3057\u305f\u30bd\u30fc\u30b9\u306f\u3053\u3061\u3089\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u8aac\u660e\u306f\u826f\u3044\u306e\u3067\u3001\u30bd\u30fc\u30b9\u3060\u3051\u78ba\u8a8d\u3057\u305f\u3044\u3063\u3066\u65b9\u306f\u3053\u3061\u3089\u3092\u3054\u53c2\u7167\u304f\u3060\u3055\u3044\u3002<\/p>\n<p><strong>GitHub<\/strong><\/p>\n<p><a href=\"https:\/\/github.com\/rust-game-samples\/actix_web_sample\/tree\/main\/jwt_user_auth\">https:\/\/github.com\/rust-game-samples\/actix_web_sample\/tree\/main\/jwt_user_auth<\/a><\/p>\n<h4><!-- notionvc: c81e2fd2-9d0a-4c6f-a43f-62b0f8d8bd72 -->API \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8<!-- notionvc: 20c9dd7c-cb64-4acb-a599-11d16a4f5f65 --><\/h4>\n<p>\u305d\u308c\u3067\u306f\u3001\u65e9\u901f\u4f5c\u6210\u3057\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n<p>\u884c\u3046\u3053\u3068\u3068\u3057\u3066\u306f\u4ee5\u4e0b\u306e\u9805\u76ee\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<ul>\n<li>\u30e6\u30fc\u30b6\u30fc\u767b\u9332<\/li>\n<li>\u30e6\u30fc\u30b6\u30fc\u30ed\u30b0\u30a4\u30f3<\/li>\n<li>\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u53d6\u5f97<\/li>\n<li>\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u5909\u66f4<\/li>\n<li>\u30e6\u30fc\u30b6\u30fc\u524a\u9664<\/li>\n<li>\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u30c8\u30fc\u30af\u30f3<\/li>\n<\/ul>\n<p>\u4e0a\u8a18\u306b\u5bfe\u3057\u3066\u306eAPI\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p><span class=\"notion-enable-hover\" spellcheck=\"false\" data-token-index=\"0\">POST \/register \uff08\u30e6\u30fc\u30b6\u30fc\u767b\u9332\uff09<\/span><!-- notionvc: 4399381a-615f-444f-bebd-1f2de1b0abee --><\/p>\n<p><span class=\"notion-enable-hover\" spellcheck=\"false\" data-token-index=\"0\">POST \/login <\/span><!-- notionvc: c6a08a42-6950-4784-8b86-12d4eb3435f0 -->\uff08\u30e6\u30fc\u30b6\u30fc\u30ed\u30b0\u30a4\u30f3\uff09<\/p>\n<p><span class=\"notion-enable-hover\" spellcheck=\"false\" data-token-index=\"0\">GET \/user\/{uuid} \uff08\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u53d6\u5f97\uff09<\/span><!-- notionvc: e5a9ab46-175f-42b0-9165-c829b5b9f55c --><\/p>\n<p><span class=\"notion-enable-hover\" spellcheck=\"false\" data-token-index=\"0\">PUT \/user\/{uuid}\uff08\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u5909\u66f4\uff09<\/span><!-- notionvc: 023e528d-febb-4794-8bd5-2a2036e5b97d --><\/p>\n<p><!-- notionvc: c5532e3d-5a31-4c2d-b58f-32564fabbb07 --><\/p>\n<p>DELETE <span class=\"notion-enable-hover\" spellcheck=\"false\" data-token-index=\"0\">\/user\/{uuid}<\/span> \u00a0\uff08\u30e6\u30fc\u30b6\u30fc\u524a\u9664\uff09<\/p>\n<p>\u305d\u308c\u3067\u306f\u3001\u65e9\u901f\u5404\u51e6\u7406\u306b\u3064\u3044\u3066\u898b\u3066\u3044\u304d\u305f\u3044\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 12711b1f-b9b3-4f4a-8235-69ebd31bf01e --><\/p>\n<h4>DB\u64cd\u4f5c<!-- notionvc: 49aedf25-4d0c-4953-80ef-4c708a3b3187 --><\/h4>\n<p>MongoDB\u306b\u30a2\u30af\u30bb\u30b9\u3057\u64cd\u4f5c\u3059\u308b\u51e6\u7406\u306frepository\u4ee5\u4e0b\u306e\u30d5\u30a1\u30a4\u30eb\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>main.rs\u3067MDBRepository\u3092\u521d\u671f\u5316\u3057\u3001mdb_repo\u3068\u3057\u3066Actix-web\u306eweb::Data\u3068\u3057\u3066\u4fdd\u6301\u3057\u307e\u3059\u3002<\/p>\n<p><strong>main.rs<\/strong><\/p>\n<p><!-- notionvc: 147d20c8-e66c-4714-a1a5-573aa3b788c6 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">let mdb_repo: MDBRepository = MDBRepository::init(COLL_NAME.to_string()).await;\n\nApp::new()\n    .app_data(web::Data::new(mdb_repo.clone()))\n    .service(register_user)<\/pre>\n<p>MDBRepository\u521d\u671f\u5316\u51e6\u7406\u3068\u3057\u3066\u306f\u3001\u74b0\u5883\u5909\u6570\u300cMONGODB_URI\u300d\u304c\u3042\u308c\u3070\u305d\u3061\u3089\u306b\u30a2\u30af\u30bb\u30b9\u306a\u3051\u308c\u3070\u3001mongodb:\/\/localhost:27017\u306b\u30a2\u30af\u30bb\u30b9\u3057\u3001MongoDB Cliant\u3092\u4f5c\u6210\u3002<\/p>\n<p>\u5f15\u6570\u300ctable_name\u300d\u3088\u308a\u3001Collection\u3092\u53d6\u5f97\u3057struct MDBRepository\u306e\u4fdd\u6301\u3059\u308b\u304b\u305f\u3061\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 07c28df5-f3c4-4300-a679-1c2d07ca56c8 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub struct MDBRepository {\n    pub client: Client,\n    pub table_name: String,\n    col: Collection&lt;RegisterUser&gt;,\n}\n  \npub async fn init(table_name: String) -&gt; MDBRepository {\n    let uri =\n        std::env::var(\"MONGODB_URI\").unwrap_or_else(|_| \"mongodb:\/\/localhost:27017\".into());\n    let client = Client::with_uri_str(uri).await.expect(\"failed to connect\");\n    create_username_index(&amp;client).await;\n    let col: Collection&lt;RegisterUser&gt; =\n        client.database(DB_NAME).collection(&amp;table_name.clone());\n\n    MDBRepository {\n        table_name,\n        client,\n        col,\n    }\n}<\/pre>\n<p>create_username_index\u30e1\u30bd\u30c3\u30c9\u306f\u3001Field\u300cemail\u300d\u3092index\u3068\u3057\u300cCOLL_NAME\u300d\u3067\u5b9a\u7fa9\u3057\u3066\u3044\u308b\u300c<span class=\"notion-enable-hover\" spellcheck=\"false\" data-token-index=\"1\">users<\/span>\u300d\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059\u3002<!-- notionvc: c12cec50-b3e9-4417-8a05-97be1bf51f0d --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">async fn create_username_index(client: &amp;Client) {\n    let options = IndexOptions::builder().unique(true).build();\n    let model = IndexModel::builder()\n        .keys(doc! { \"email\": 1 })\n        .options(options)\n        .build();\n    client\n        .database(DB_NAME)\n        .collection::&lt;RegisterUser&gt;(COLL_NAME)\n        .create_index(model, None)\n        .await\n        .expect(\"creating an index should succeed\");\n}<\/pre>\n<h4>\u30e6\u30fc\u30b6\u30fc\u767b\u9332<!-- notionvc: 670463f7-efff-4a2e-a84e-472e18497efe --><\/h4>\n<p>\u305d\u308c\u3067\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u306eAPI\u3092\u898b\u3066\u3044\u3053\u3046\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p>\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u306eAPI\u306f\u3001api\u306eregister_user\u30e1\u30bd\u30c3\u30c9\u3067\u5b9a\u7fa9\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>main.rs\u3067\u3001service\u3068\u3057\u3066\u767b\u9332\u3057\u307e\u3059\u3002<\/p>\n<p>\u00a0<\/p>\n<p><!-- notionvc: f860e325-531e-44d2-b7d1-3dd8349d1412 --><\/p>\n<p>register_user<!-- notionvc: 051a1209-2ccb-4df3-9b69-b2dce6ea0c21 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">App::new()\n    .app_data(web::Data::new(mdb_repo.clone()))\n    .service(register_user)<\/pre>\n<p>\u30e6\u30fc\u30b6\u30fc\u767b\u9332API\u306e\u51e6\u7406\u3067\u3042\u308b\u3001register_user\u30e1\u30bd\u30c3\u30c9\u306e\u5168\u4f53\u50cf\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u4e3b\u306a\u6d41\u308c\u3068\u3057\u3066\u306f\u3001\u30d5\u30ed\u30f3\u30c8\u304b\u3089\u300cemail\u300d\u3068\u300cpassword\u300d\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u53d7\u3051\u3001\u767b\u9332\u3059\u308b\u30e6\u30fc\u30b6\u3092\u4f5c\u6210\u3057\u3001MongoDB\u306e\u767b\u9332\u3057\u3001\u6210\u529f\u3059\u308c\u3070JWT\u306e\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u3068\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u30c8\u30fc\u30af\u30f3\u3092\u30ec\u30b9\u30dd\u30f3\u30b9\u3068\u3057\u3066\u8fd4\u5374\u3002\u3068\u3044\u3046\u6d41\u308c\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 4a9a2c6b-3eef-4345-a776-0f33d5e82406 --><\/p>\n<p>\u00a0<\/p>\n<p>api\/user.rs<!-- notionvc: b23a98a6-d44e-4a30-b7b0-bde0a29c1012 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">async fn register_user(\n    ddb_repo: Data&lt;MDBRepository&gt;,\n    request: Json&lt;SubmitUserRequest&gt;,\n) -&gt; Result&lt;HttpResponse, ServiceError&gt; {\n    let new_user = RegisterUser::new(request.email.clone(), request.password.clone());\n    let result = ddb_repo.post_user(new_user.clone()).await;\n    let uuid = new_user.get_uuid();\n\n    match result {\n        Ok(_) =&gt; {\n            let token = create_access_token(uuid.clone())?;\n            let refresh = create_refresh_token(uuid.clone())?;\n\n            Ok(HttpResponse::Ok().json(ResponseBody::new(\n                MESSAGE_SIGNUP_SUCCESS,\n                CreateTokenResponse {\n                    token,\n                    refresh_token: refresh,\n                },\n            )))\n        }\n        Err(err) =&gt; Err(ServiceError::InternalServerError {\n            error_message: err.to_string(),\n        }),\n    }\n}<\/pre>\n<p>\u30d5\u30ed\u30f3\u30c8\u304b\u3089\u300cemail\u300d\u3068\u300cpassword\u300d\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u53d7\u3051\u308b\u305f\u3081\u3001struct SubmitUserRequest\u3092\u4f5c\u6210\u3002\u305d\u308c\u3092\u5143\u306b\u3001RegisterUser\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u751f\u6210\u3002<!-- notionvc: 25579893-33f8-4732-b9cf-96f6433b5f7e --><\/p>\n<p>\u00a0<\/p>\n<p><strong>model\/<span class=\"notion-enable-hover\" data-token-index=\"1\">user.rs<\/span><\/strong><!-- notionvc: 0a165956-2385-4d24-a3a0-bc837b90727e --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub struct SubmitUserRequest {\n    pub email: String,\n    pub password: String,\n}<\/pre>\n<p>RegisterUser\u751f\u6210\u306b\u306f\u3001uuid\u3092\u767a\u884c\u3002first_name\u3068last_name\u306a\u3069\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u306f\u53d6\u308a\u6562\u3048\u305a\u7a7a\u6587\u5b57\u767b\u9332\u3002<!-- notionvc: bc58d7a5-d709-4db9-9ff3-e07dc951868d --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub struct RegisterUser {\n    pub uuid: String,\n    pub first_name: String,\n    pub last_name: String,\n    pub username: String,\n    pub email: String,\n    pub password: String,\n}<\/pre>\n<p>RegisterUser\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306enew_user\u3092ddb_repo\u306epost_user\u30e1\u30bd\u30c3\u30c9\u306e\u5f15\u6570\u306b\u6e21\u3057\u3001\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u306eDB\u51e6\u7406\u3092\u884c\u3063\u3066\u3044\u304d\u307e\u3059\u3002<!-- notionvc: 3e2def9b-8eea-49ae-a209-f90f7a6d01df --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">let result = ddb_repo.post_user(new_user.clone()).await;<\/pre>\n<p>\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u306eDB\u51e6\u7406\u3067\u3042\u308b\u3001MDBRepository\u306epost_user\u30e1\u30bd\u30c3\u30c9\u306f\u81f3\u3063\u3066\u30b7\u30f3\u30d7\u30eb\u3002<\/p>\n<p>\u81ea\u5206\u81ea\u8eab\u304c\u4fdd\u6301\u3059\u308b\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u300cusers\u300d\u306b\u5bfe\u3057\u3066\u300cinsert_one\u300d\u3067MongoDB\u306b\u767b\u9332\u3092\u884c\u3044\u307e\u3059\u3002\u6210\u529f\u3059\u308c\u3070\u305d\u306e\u307e\u307eresult\u3092\u8fd4\u5374\u3002<\/p>\n<p><!-- notionvc: 8cbeb442-1ce2-4106-b770-ec4cdaae1a0b --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub async fn post_user(&amp;self, user: RegisterUser) -&gt; Result&lt;InsertOneResult, ServiceError&gt; {\n    let result = self.col.insert_one(user, None).await;\n\n    match result {\n        Ok(user_result) =&gt; Ok(user_result),\n        Err(_) =&gt; Err(ServiceError::CreationFailure {\n            error_message: MESSAGE_SIGNUP_FAILED.to_string(),\n        }),\n    }\n}<\/pre>\n<p>MDBRepository\u306epost_user\u30e1\u30bd\u30c3\u30c9\u304b\u3089\u8fd4\u5374\u3055\u308c\u305fresult\u304c\u554f\u984c\u306a\u3051\u308c\u3070\u3001\u30d5\u30ed\u30f3\u30c8\u3078\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u306b\u306f\u3001\u30c8\u30fc\u30af\u30f3\u3092\u542b\u3093\u3060\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u8fd4\u5374\u3057\u307e\u3059\u3002<\/p>\n<p>\u30a8\u30e9\u30fc\u306e\u5834\u5408\u306f\u305d\u306e\u307e\u307e\u30a8\u30e9\u30fc\u3092\u8fd4\u5374\u3002<\/p>\n<p><!-- notionvc: 467b721d-554c-4056-a73f-618cf267951a --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">match result {\n      Ok(_) =&gt; {\n          let token = create_access_token(uuid.clone())?;\n          let refresh = create_refresh_token(uuid.clone())?;\n\n          Ok(HttpResponse::Ok().json(ResponseBody::new(\n              MESSAGE_SIGNUP_SUCCESS,\n              CreateTokenResponse {\n                  token,\n                  refresh_token: refresh,\n              },\n          )))\n      }\n      Err(err) =&gt; Err(ServiceError::InternalServerError {\n          error_message: err.to_string(),\n      }),\n  }<\/pre>\n<p>create_access_token\u3084create_refresh_token\u3067JWT\u30c8\u30fc\u30af\u30f3\u3092\u4f5c\u6210\u3059\u308b\u306e\u3067\u3059\u304c\u3001\u4eca\u56de\u306f\u30e6\u30fc\u30b6\u30fcID\u3067\u3042\u308b\u3001uuid\u3082claims\u306b\u542b\u3081\u4f5c\u6210\u3057\u307e\u3059\u3002<\/p>\n<p>JWT\u306e\u4f5c\u6210\u51e6\u7406\u306a\u3069\u306b\u95a2\u3057\u3066\u306f<a href=\"https:\/\/www.webcyou.com\/?p=11748\">\u524d\u56de\u306e\u8a18\u4e8b<\/a>\u3092\u3054\u53c2\u7167\u3044\u305f\u3060\u3051\u308c\u3070\u3068\u601d\u3044\u3001\u4eca\u56de\u306f\u5272\u611b\u3044\u305f\u3057\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: c8c82966-60ea-40c7-942a-40b394e941c8 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub fn create_access_token(uuid: String) -&gt; Result&lt;String, ServiceError&gt; {\n    let claims = create_custom_claims(false, uuid, Duration::from_mins(15));\n    claims_authenticate(claims)\n}<\/pre>\n<p>\u3053\u308c\u3067\u3001\u8fd4\u5374\u3055\u308c\u305f\u30c8\u30fc\u30af\u30f3\u3092\u7528\u3044\u3066\u30a2\u30af\u30bb\u30b9\u5236\u9650\u3055\u308c\u3066\u3044\u308bAPI\u306b\u30a2\u30af\u30bb\u30b9\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u306e\u6d41\u308c\u306f\u4ee5\u4e0a\u3067\u3001\u7d9a\u3044\u3066\u30ed\u30b0\u30a4\u30f3\u51e6\u7406\u3092\u898b\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306f\u30b5\u30f3\u30d7\u30eb\u306a\u306e\u3067\u7c21\u6613\u306e\u5b9f\u88c5\u3067\u306f\u3042\u308a\u307e\u3059\u304c\u3001\u672c\u756a\u74b0\u5883\u7b49\u306e\u5834\u5408\u306f\u30e1\u30fc\u30eb\u78ba\u8a8d\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u9762\u3001\u6392\u4ed6\u51e6\u7406\u306a\u3069\u3092\u9069\u5207\u306b\u884c\u3046\u3053\u3068\u304c\u91cd\u8981\u3068\u306a\u308b\u3053\u3068\u3092\u8a8d\u8b58\u3044\u305f\u3060\u3051\u308c\u3070\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 33df2022-9569-47ed-aaf7-1878095d83a7 --><\/p>\n<h4>\u30ed\u30b0\u30a4\u30f3<\/h4>\n<p>\u7d9a\u3044\u3066\u3001\u30ed\u30b0\u30a4\u30f3\u51e6\u7406\u3092\u4f5c\u6210\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<p>API\u306flogin_user\u30e1\u30bd\u30c3\u30c9\u3068\u306a\u308a\u307e\u3059\u306e\u3067\u3001\u767b\u9332\u540c\u69d8service\u306b\u767b\u9332\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 49294f98-ef63-4e0b-96bc-47dbf0f89b2e --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">.service(login_user)<\/pre>\n<p>API\u306elogin_user\u30e1\u30bd\u30c3\u30c9\u3082\u767b\u9332\u306e\u6d41\u308c\u3068\u307b\u3068\u3093\u3069\u540c\u3058\u3067\u3001MDBRepository\u306elogin_user\u30e1\u30bd\u30c3\u30c9\u306bemail\u3068password\u3092\u5f15\u6570\u3067\u6e21\u3057\u5b9f\u884c\u3057\u307e\u3059\u3002<\/p>\n<p>\u6210\u529f\u3059\u308c\u3070\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u3068\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u30c8\u30fc\u30af\u30f3\u3092\u30ec\u30b9\u30dd\u30f3\u30b9\u3067\u8fd4\u5374\u3059\u308b\u3068\u3053\u308d\u306f\u3001\u5148\u307b\u3069\u5ea6\u3068\u540c\u69d8\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 7a110339-1d28-4a78-bd94-df5a2a52ac6d --><\/p>\n<p><strong>api\/user.rs<\/strong><!-- notionvc: 0b467234-180a-4d00-9832-430571236a41 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">async fn login_user(\n    ddb_repo: Data&lt;MDBRepository&gt;,\n    request: Json&lt;SubmitUserRequest&gt;,\n) -&gt; Result&lt;HttpResponse, ServiceError&gt; {\n    let result = ddb_repo.login_user(&amp;request.email, &amp;request.password).await;\n\n    match result {\n        Ok(user) =&gt; {\n            let token = create_access_token(user.get_uuid())?;\n            let refresh = create_refresh_token(user.get_uuid())?;\n\n            Ok(HttpResponse::Ok().json(ResponseBody::new(\n                MESSAGE_LOGIN_SUCCESS,\n                CreateTokenResponse {\n                    token,\n                    refresh_token: refresh,\n                },\n            )))\n        }\n        Err(err) =&gt; Err(ServiceError::InternalServerError {\n            error_message: err.to_string(),\n        }),\n    }\n}<\/pre>\n<p>MDBRepository\u306elogin_user\u30e1\u30bd\u30c3\u30c9\u306f\u3001email\u3092key\u3068\u3057\u3066find_one\u3067\u691c\u7d22\u3057\u3001\u30cf\u30c3\u30b7\u30e5\u5316\u3055\u308c\u305f\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u691c\u8a3c\u3092\u884c\u3044\u3001\u554f\u984c\u306a\u3051\u308c\u3070\u30ec\u30b9\u30dd\u30f3\u30b9\u7528\u30b9\u30ad\u30fc\u30de\u3092\u6301\u3063\u305fUser\u30c7\u30fc\u30bf\u3092JSON\u3067\u8fd4\u5374\u3057\u307e\u3059\u3002<\/p>\n<p><strong>repository\/mdb.rs<\/strong><\/p>\n<p><!-- notionvc: 3b2db005-ee0f-489d-8ea4-52f778c7cfa4 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub async fn login_user(&amp;self, email: &amp;str, password: &amp;str) -&gt; Result&lt;User, ServiceError&gt; {\n    let collection: Collection&lt;RegisterUser&gt; =\n        self.client.database(DB_NAME).collection(&amp;self.table_name);\n\n    match collection.find_one(doc! {\"email\": email}, None).await {\n        Ok(Some(user_data)) =&gt; {\n            if verify(password, &amp;user_data.password).unwrap() {\n                Ok(User::from_register_data(user_data))\n            } else {\n                Err(ServiceError::Unauthorized {\n                    error_message: MESSAGE_LOGIN_FAILED.to_string(),\n                })\n            }\n        }\n        Ok(None) =&gt; Err(ServiceError::Unauthorized {\n            error_message: MESSAGE_LOGIN_FAILED.to_string(),\n        }),\n        Err(_) =&gt; Err(ServiceError::InternalServerError {\n            error_message: \"\".to_string(),\n        }),\n    }\n}<\/pre>\n<p>\u00a0<\/p>\n<h4>\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u53d6\u5f97<!-- notionvc: fa54c821-546c-4dfc-b524-1ab7038cd6f4 --><\/h4>\n<p>\u7d9a\u3044\u3066\u3001\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u53d6\u5f97\u306a\u306e\u3067\u3059\u304c\u3001\u3053\u3061\u3089\u306f\u30e6\u30fc\u30b6\u30fc\u304c\u30ed\u30b0\u30a4\u30f3\u8a8d\u8a3c\u3092\u7d4c\u3066\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u3092\u7528\u3044\u3066\u30a2\u30af\u30bb\u30b9\u3059\u308b\u8a8d\u53efAPI\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u306a\u306e\u3067\u3001\u4e8b\u524d\u306b\u30ed\u30b0\u30a4\u30f3\u3057\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u3092\u53d6\u5f97\u3057\u3001Request\u30d8\u30c3\u30c0\u30fc\u306b\u4ed8\u4e0e\u3057\u3066\u9001\u4fe1\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 0770e7be-cb17-40d2-99fb-0ee19037d154 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">web::scope(\"\/user\")\n     .service(get_user)<\/pre>\n<p>URI\u306b\u4ed8\u4e0e\u3055\u308c\u305fuuid\u3068\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u5185\u306euuid\u3092\u691c\u8a3c\u3057\u4e00\u81f4\u3057\u305f\u5834\u5408\u3001\u305d\u306e\u30e6\u30fc\u30b6\u30fc\u306e\u60c5\u5831\u3092\u8fd4\u5374\u3059\u308b\u5f62\u3068\u306a\u3063\u3066\u304a\u308a\u307e\u3059\u3002<\/p>\n<p><strong>api\/user.rs<\/strong><\/p>\n<p><!-- notionvc: fdbf4624-501e-4bf9-a5b7-4d843a5337d2 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">async fn get_user(\n    ddb_repo: Data&lt;MDBRepository&gt;,\n    uuid: Path&lt;String&gt;,\n    request: HttpRequest,\n) -&gt; Result&lt;HttpResponse, ServiceError&gt; {\n    let user_id = uuid.into_inner();\n\n    let token = get_token(request)?;\n    let claims = claims_verify_token(&amp;token)?;\n\n    if claims.custom.refresh {\n        return Err(ServiceError::BadRequest {\n            error_message: MESSAGE_REFRESH_TOKEN_ERROR.to_string(),\n        });\n    }\n    let sub_uuid = get_sub_uuid(&amp;claims, &amp;user_id)?;\n    let result = ddb_repo.get_user(sub_uuid.clone()).await;\n    match result {\n        Ok(user) =&gt; Ok(HttpResponse::Ok().json(ResponseBody::new(MESSAGE_OK, user))),\n        Err(err) =&gt; Err(err),\n    }\n}<\/pre>\n<p>get_token\u3001claims_verify_token\u306e\u6d41\u308c\u306f\u524d\u56de\u306e\u8a18\u4e8b\u306e\u5f62\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u307e\u305f\u3053\u3053\u3067\u306f\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u306e\u307f\u3092\u8a31\u53ef\u3059\u308b\u306e\u3067\u3001\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u30c8\u30fc\u30af\u30f3\u306e\u5834\u5408\u306f\u30a8\u30e9\u30fc\u51e6\u7406\u3092\u5165\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>get_sub_uuid\u3067\u3001claims\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308buuid\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: d397a975-0841-4d28-99d1-c933d291ffd3 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">let sub_uuid = get_sub_uuid(&amp;claims, &amp;user_id)?;<\/pre>\n<p>repository\u5074\u3067\u306f\u3001\u8a8d\u8a3c\u304c\u901a\u3063\u305fuuid\u304c\u6765\u308b\u60f3\u5b9a\u306a\u306e\u3067\u3001\u305d\u3061\u3089\u3092\u5143\u306bfind_one\u3092\u884c\u3044\u30e6\u30fc\u30b6\u30fc\u3092\u691c\u7d22\u3057\u3001\u30de\u30c3\u30c1\u3057\u305f\u5834\u5408user\u3092\u8fd4\u5374\u3057\u307e\u3059\u3002<\/p>\n<p><strong>repository\/mdb.rs<\/strong><\/p>\n<p><!-- notionvc: 99ef6f6a-a3da-4274-8011-0290272b871a --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub async fn get_user(&amp;self, uuid: String) -&gt; Result&lt;User, ServiceError&gt; {\n    let collection: Collection&lt;User&gt; =\n        self.client.database(DB_NAME).collection(&amp;self.table_name);\n\n    match collection.find_one(doc! { \"uuid\": &amp;uuid }, None).await {\n        Ok(Some(user)) =&gt; Ok(user),\n        Ok(None) =&gt; Err(ServiceError::BadRequest {\n            error_message: MESSAGE_BAD_REQUEST.to_string(),\n        }),\n        Err(_) =&gt; Err(ServiceError::InternalServerError {\n            error_message: MESSAGE_INTERNAL_SERVER_ERROR.to_string(),\n        }),\n    }\n}<\/pre>\n<h4>\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u5909\u66f4<\/h4>\n<p>\u7d9a\u3044\u3066\u3001\u30e6\u30fc\u30b6\u30fc\u60c5\u5831\u5909\u66f4\u51e6\u7406\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>API\u306e\u51e6\u7406\u306f\u4ee5\u4e0b\u306e\u3068\u304a\u308a\u3067\u3059\u3002<\/p>\n<p><!-- notionvc: 566e737f-61d6-49fe-adec-fece9c1546d2 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">#[put(\"\/{uuid}\")]\nasync fn update_user(\n    ddb_repo: Data&lt;MDBRepository&gt;,\n    uuid: Path&lt;String&gt;,\n    request: HttpRequest,\n    put_user: Json&lt;PutUserRequest&gt;,\n) -&gt; Result&lt;HttpResponse, ServiceError&gt; {\n    let user_id = uuid.into_inner();\n    let token = get_token(request)?;\n    let claims = claims_verify_token(&amp;token)?;\n\n    if claims.custom.refresh {\n        return Err(ServiceError::BadRequest {\n            error_message: MESSAGE_REFRESH_TOKEN_ERROR.to_string(),\n        });\n    }\n    let sub_uuid = get_sub_uuid(&amp;claims, &amp;user_id)?;\n    let new_user = User::from_put(user_id.clone(), put_user);\n    let result = ddb_repo.put_user(sub_uuid.clone(), new_user).await;\n\n    match result {\n        Ok(user) =&gt; Ok(HttpResponse::Ok().json(ResponseBody::new(MESSAGE_OK, user))),\n        Err(err) =&gt; Err(err),\n    }\n}<\/pre>\n<p>\u30e6\u30fc\u30b6\u30fc\u306euuid\u3092\u53d6\u5f97\u3059\u308bget_sub_uuid\u306a\u3069\u306f\u5148\u7a0b\u3068\u540c\u3058\u5f62\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u30c7\u30fc\u30bf\u304c\u66f4\u65b0\u3055\u308c\u305fUser\u306e\u60c5\u5831\u3092<span class=\"notion-enable-hover\" spellcheck=\"false\" data-token-index=\"0\">PutUserRequest <\/span>\u306e\u69cb\u9020\u4f53\u3068\u3057\u3066\u53d7\u53d6\u308a\u3001User::from_put\u3067\u66f4\u65b0\u7528\u306e\u30e6\u30fc\u30b6\u30fc\u3092\u4f5c\u6210\u3057\u3001\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u884c\u3046\u51e6\u7406\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 6ce4ef8a-951f-4215-b7df-d9679af2938c --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">let new_user = User::from_put(user_id.clone(), put_user);\nlet result = ddb_repo.put_user(sub_uuid.clone(), new_user).await;<\/pre>\n<p>repository\u5074\u3067\u3001\u66f4\u65b0\u3059\u308b\u30c7\u30fc\u30bf\u3092\u53d7\u53d6\u308a\u3001first_name\u3001last_name\u3001username\u306e\u307f\u66f4\u65b0\u3059\u308b\u6d41\u308c\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u4f5c\u6210\u3057\u305f\u5f8c\u306b\u3001PUT\u3067\u306f\u306a\u304f\u3001PATCH\u306e\u304c\u9069\u5207\u3060\u306a\u3068\u601d\u3044\u307e\u3057\u305f\u304c\u305d\u306e\u307e\u307e\u306b\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p><strong>repository\/mdb.rs<\/strong><\/p>\n<p><!-- notionvc: 0ab84eda-68e3-4d4a-a847-7670bf7d007f --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub async fn put_user(&amp;self, uuid: String, user: User) -&gt; Result&lt;User, ServiceError&gt; {\n    let collection: Collection&lt;User&gt; =\n        self.client.database(DB_NAME).collection(&amp;self.table_name);\n    let filter = doc! {\"uuid\": uuid};\n    let update = doc! {\n        \"$set\":\n            {\n                \"first_name\": user.first_name,\n                \"last_name\": user.last_name,\n                \"username\": user.username,\n                \/\/ \"email\": user.email\n            },\n    };\n\n    let options = mongodb::options::FindOneAndUpdateOptions::builder()\n        .return_document(mongodb::options::ReturnDocument::After)\n        .build();\n\n    match collection\n        .find_one_and_update(filter, update, options)\n        .await\n    {\n        Ok(Some(updated_user)) =&gt; Ok(updated_user),\n        Ok(None) =&gt; Err(ServiceError::UpdateFailure {\n            error_message: MESSAGE_CAN_NOT_UPDATE_DATA.to_string(),\n        }),\n        Err(_) =&gt; Err(ServiceError::InternalServerError {\n            error_message: MESSAGE_INTERNAL_SERVER_ERROR.to_string(),\n        }),\n    }\n}\n<\/pre>\n<h3>\u30e6\u30fc\u30b6\u30fc\u524a\u9664<\/h3>\n<p>\u6700\u5f8c\u306b\u3001\u30e6\u30fc\u30b6\u30fc\u306e\u524a\u9664\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u30e6\u30fc\u30b6\u30fc\u81ea\u8eab\u3092\u524a\u9664\u3059\u308bAPI\u306f\u3061\u3087\u3063\u3068\u5909\u306a\u611f\u3058\u3057\u307e\u3059\u304c\u3001\u3068\u308a\u3042\u3048\u305a\u30e6\u30fc\u30b6\u30fc\u306eCRUD\u3068\u3057\u3066\u5165\u308c\u3066\u7f6e\u304d\u307e\u3057\u305f\u3002<\/p>\n<p>API\u306f\u3001api\u306edelete_user\u30e1\u30bd\u30c3\u30c9\u3067\u5b9a\u7fa9\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p><!-- notionvc: 0f580c64-9e3f-4bf5-98bf-02f7a3bc9591 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">.service(delete_user),<\/pre>\n<p>\u3053\u308c\u307e\u3067\u3068\u3001\u307b\u307c\u307b\u307c\u540c\u3058\u5f62\u3068\u306a\u308a\u307e\u3059\u3002<!-- notionvc: 2a182b33-da78-40f7-a006-6d03adc1d7e3 --><\/p>\n<p>\u00a0<\/p>\n<p><strong>api\/user.rs<\/strong><!-- notionvc: c541fcb3-6271-41c7-8279-c9ed3276ac68 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">#[delete(\"\/{id}\")]\npub async fn delete_user(\n    ddb_repo: Data&lt;MDBRepository&gt;,\n    uuid: Path&lt;String&gt;,\n    request: HttpRequest,\n) -&gt; Result&lt;HttpResponse, ServiceError&gt; {\n    let user_id = uuid.into_inner();\n    let token = get_token(request)?;\n    let claims = claims_verify_token(&amp;token)?;\n\n    if claims.custom.refresh {\n        return Err(ServiceError::BadRequest {\n            error_message: MESSAGE_REFRESH_TOKEN_ERROR.to_string(),\n        });\n    }\n\n    let sub_uuid = get_sub_uuid(&amp;claims, &amp;user_id)?;\n    let result = ddb_repo.delete_user(sub_uuid.clone()).await;\n    match result {\n        Ok(uuid) =&gt; Ok(HttpResponse::Ok().json(ResponseBody::new(MESSAGE_OK, uuid))),\n        Err(err) =&gt; Err(err),\n    }\n}<\/pre>\n<p>\u3053\u3061\u3089\u3082\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u306e\u307f\u306e\u8a8d\u53ef\u3068\u306a\u308a\u307e\u3059\u306e\u3067\u3001\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u30c8\u30fc\u30af\u30f3\u306e\u5834\u5408\u306f\u30a8\u30e9\u30fc\u3092\u8fd4\u5374\u3002<!-- notionvc: 4ed4669c-e62e-44cd-9b76-d1a84e9924af --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">let claims = claims_verify_token(&amp;token)?;\n\nif claims.custom.refresh {\n    return Err(ServiceError::BadRequest {\n        error_message: MESSAGE_REFRESH_TOKEN_ERROR.to_string(),\n    });\n}<\/pre>\n<p>\u3053\u3061\u3089\u3082\u3001\u3053\u308c\u307e\u3067\u306e\u6d41\u308c\u306e\u3088\u3046\u306b\u3001uuid\u3092\u5143\u306b\u30e6\u30fc\u30b6\u30fc\u3092\u691c\u7d22\u3057\u3001\u524a\u9664\u3059\u308b\u51e6\u7406\u3092\u884c\u3063\u3066\u3044\u3066\u3001\u898b\u3064\u304b\u3089\u306a\u3044\u5834\u5408\u306f\u30a8\u30e9\u30fc\u3092\u8fd4\u5374\u3057\u3066\u304a\u308a\u307e\u3059\u3002<\/p>\n<p><strong>repository\/mdb.rs<\/strong><\/p>\n<p><!-- notionvc: 865208da-5703-413a-a108-aecb234b1ff9 --><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"rust\">pub async fn delete_user(&amp;self, uuid: String) -&gt; Result&lt;String, ServiceError&gt; {\n    let collection: Collection&lt;User&gt; =\n        self.client.database(DB_NAME).collection(&amp;self.table_name);\n    let filter = doc! {\"uuid\": &amp;uuid};\n\n    match collection.delete_one(filter, None).await {\n        Ok(delete_result) =&gt; {\n            if delete_result.deleted_count == 0 {\n                Err(ServiceError::NotFound {\n                    error_message: \"User not found\".to_string(),\n                })\n            } else {\n                Ok(uuid)\n            }\n        }\n        Err(_) =&gt; Err(ServiceError::InternalServerError {\n            error_message: MESSAGE_INTERNAL_SERVER_ERROR.to_string(),\n        }),\n    }\n}<\/pre>\n<p>\u00a0<\/p>\n<h4>\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u30c8\u30fc\u30af\u30f3<\/h4>\n<p>\u4e3b\u306b\u3001<a href=\"https:\/\/www.webcyou.com\/?p=11748\">\u524d\u56de\u306e\u8a18\u4e8b<\/a>\u3067\u8aac\u660e\u3057\u3066\u3044\u308b\u3053\u3068\u3082\u3042\u3063\u3066\u3001\u4eca\u56de\u306f\u5272\u611b\u3055\u305b\u3066\u3044\u305f\u3060\u304d\u307e\u3059\u3002<\/p>\n<p>\u3068\u3044\u3046\u308f\u3051\u3067\u3001\u99c6\u3051\u8db3\u3067\u3056\u3063\u3068\u3067\u306f\u3042\u308a\u307e\u3057\u305f\u304c\u3001MongoDB\u306b\u30e6\u30fc\u30b6\u30fc\u3092\u767b\u9332\u3057\u3001\u30ed\u30b0\u30a4\u30f3\u8a8d\u8a3c\u3092\u7d4c\u3066\u3001API\u306e\u8a8d\u53ef\u3092\u884c\u3044\u307e\u3057\u305f\u3002<\/p>\n<p>Rust\u3067\u30b5\u30fc\u30d0\u30fc\u958b\u767a\u3082\u5168\u7136\u3042\u308a\u306a\u306e\u304c\u5206\u304b\u3063\u3066\u304d\u307e\u3057\u305f\u306e\u3067\u3001\u73fe\u5728\u5b9f\u969b\u306b\u30b5\u30fc\u30d3\u30b9\u3092\u958b\u767a\u3057\u3066\u3044\u308b\u9014\u4e2d\u3067\u306f\u3042\u308a\u307e\u3059\u3002<\/p>\n<p>\u3088\u308d\u3057\u3051\u308c\u3070\u3001Rust\u3067\u30b5\u30fc\u30d0\u30fc\u958b\u767a\u3082\u3044\u304b\u304c\u3067\u3057\u3087\u3046\u304b\u3002<\/p>\n<p>\u3067\u306f\u3067\u306f\u3041\u3002<\/p>\n<p><!-- notionvc: 9e889762-e395-4764-8861-a5ab78baa79d --><\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3069\u3082\u3067\u3059\u3002 \u4eca\u56de\u306f\u524d\u56de\u306e\u300cRust \u2013 Actix Web JWT \u8a8d\u8a3c\u8a8d\u53ef API\u306e\u4f5c\u6210\u300d\u306e\u7d9a\u304d\u3068\u306a\u308a\u3001\u307e\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u3057\u3066MongoDB\u3092\u7528\u3044\u308b\u5f62\u3068\u306a\u308a\u307e\u3059\u3002 \u74b0\u5883\u8a2d\u5b9a\u306a\u3069\u306b\u95a2\u3057\u3066\u306f\u3001\u4ee5\u524d\u306e\u8a18\u4e8b\u300cRust \u2013 Ac [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":11750,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[299],"tags":[330,166,37,327,105,178,78,118],"class_list":["post-11811","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-rust","tag-actix-web","tag-iphone","tag-iphone-","tag-rust","tag-web","tag-178","tag-78","tag-118"],"_links":{"self":[{"href":"https:\/\/www.webcyou.com\/index.php?rest_route=\/wp\/v2\/posts\/11811","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcyou.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcyou.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcyou.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcyou.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11811"}],"version-history":[{"count":3,"href":"https:\/\/www.webcyou.com\/index.php?rest_route=\/wp\/v2\/posts\/11811\/revisions"}],"predecessor-version":[{"id":11814,"href":"https:\/\/www.webcyou.com\/index.php?rest_route=\/wp\/v2\/posts\/11811\/revisions\/11814"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcyou.com\/index.php?rest_route=\/wp\/v2\/media\/11750"}],"wp:attachment":[{"href":"https:\/\/www.webcyou.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcyou.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcyou.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}