[{"data":1,"prerenderedAt":1141},["ShallowReactive",2],{"article-nuxt-auth-middleware":3},{"id":4,"title":5,"body":6,"category":1125,"createdAt":1127,"description":1128,"extension":1129,"index":1130,"meta":1131,"navigation":1132,"path":1133,"publish":1132,"seo":1134,"series":1130,"seriesTitle":1130,"stem":1135,"tag":1136,"thumbnail":1139,"updatedAt":1130,"__hash__":1140},"articles\u002Farticles\u002Fnuxt-auth-middleware.md","Nuxt.jsのSSR・SPA時のフロント側の認証ビューを自前で実装する",{"type":7,"value":8,"toc":1113},"minimark",[9,13,16,19,32,35,38,42,45,48,51,54,66,70,73,139,142,212,215,222,309,312,315,437,444,479,484,489,496,593,703,707,714,718,729,732,914,917,921,928,1089,1092,1095,1098,1109],[10,11,12],"p",{},"こんにちはjunです。webアプリを作成する時は大体、認証機能をつけることが多いです。LaravelやDjangoなどでは一発で行けますが、Nuxt.js、Vue.jsを使用したSPA、Node.jsでのSSRコンテンツを作成する場合は一捻り必要です。",[10,14,15],{},"Nuxt.jsなどで作成するアプリはバックエンドと独立し、都度バックエンドへのAPI通信の際にトークンを渡したりすることで認証が必要なAPIへアクセスしています。",[10,17,18],{},"ビュー側の処理でも",[20,21,22,26,29],"ul",{},[23,24,25],"li",{},"ログインしているユーザーはこのように表示",[23,27,28],{},"このルートはログインしているユーザーのみアクセス可能",[23,30,31],{},"未ログインユーザーはログイン画面移動",[10,33,34],{},"といった処理が行われることが多いです。この記事では上記のような認証を用いたビューの表現、ルーターの設定をNuxt.jsでどう行うかの解説をしたいと思います。SPA（クライアントサイドレンダリング）とSSR（サーバーサイドレンダリング）の２パターンを実装します。ちなみにnuxt-authなどのライブラリは使用しません。",[10,36,37],{},"また、ログインメソッドの処理やリクエストヘッダにどうこうするとか、バックエンド側の処理については今回は解説しません。あくまでフロント側（Nuxt.js側）の表示やロジックに認証が必要な場合にどう実装するかについて解説するのみです。",[39,40,41],"h2",{"id":41},"大まかな処理",[10,43,44],{},"まずこの実装を行うにあたりJWTやクッキーなどなんらかの認証トークンが取得できていること、またそれらの値を使用できることを前提として進めます。",[10,46,47],{},"LaravelやDjangoなどではリクエストを送る際にヘッダーにセッションIDを含むクッキーを送信することで、サーバー側でログインによるビューやロジックの分岐を行っています。",[10,49,50],{},"しかしNuxt.jsでSPAの場合はコンテンツをクライアント側で生成し、またSSRの場合はnode.jsのサーバーで行われます。すなわちセッションやユーザー情報を保存しているAPIサーバーから「どうにかしてNuxt.js側にユーザー情報を渡す」必要があります。",[10,52,53],{},"これから実装する内容はSSR、SPAどちらも以下の通りです。",[55,56,57,60,63],"ol",{},[23,58,59],{},"Nuxt.js側でユーザーの情報を保存する。",[23,61,62],{},"ログインの是非はユーザー情報の有無で判断する。",[23,64,65],{},"何かしらのタイミングでユーザー情報を取得するAPIを都度発行する。",[39,67,69],{"id":68},"storeの調整","Storeの調整",[10,71,72],{},"ではまずStoreにて以下のようにuserステートを作成します。",[74,75,81],"pre",{"className":76,"code":77,"filename":78,"language":79,"meta":80,"style":80},"language-javascript shiki shiki-themes material-theme-ocean","export const state = () => ({\n    user:null,\n});\n","store\u002Findex.js","javascript","",[82,83,84,117,127],"code",{"__ignoreMap":80},[85,86,89,93,97,101,105,108,111,114],"span",{"class":87,"line":88},"line",1,[85,90,92],{"class":91},"s6cf3","export",[85,94,96],{"class":95},"sJ14y"," const",[85,98,100],{"class":99},"s0W1g"," state ",[85,102,104],{"class":103},"sAklC","=",[85,106,107],{"class":103}," ()",[85,109,110],{"class":95}," =>",[85,112,113],{"class":99}," (",[85,115,116],{"class":103},"{\n",[85,118,120,124],{"class":87,"line":119},2,[85,121,123],{"class":122},"s-wAU","    user",[85,125,126],{"class":103},":null,\n",[85,128,130,133,136],{"class":87,"line":129},3,[85,131,132],{"class":103},"}",[85,134,135],{"class":99},")",[85,137,138],{"class":103},";\n",[10,140,141],{},"デフォルトではnullにしておきます。このuserステートがnullでなく、ユーザー情報のオブジェクトである場合をログイン状態とします。mutationなどでこのステートに値をセットできるように作っておきます。",[74,143,145],{"className":76,"code":144,"filename":78,"language":79,"meta":80,"style":80},"export const mutations = {\n    setUser(state,{user}){\n            state.user = user;\n    }\n}\n",[82,146,147,161,182,200,206],{"__ignoreMap":80},[85,148,149,151,153,156,158],{"class":87,"line":88},[85,150,92],{"class":91},[85,152,96],{"class":95},[85,154,155],{"class":99}," mutations ",[85,157,104],{"class":103},[85,159,160],{"class":103}," {\n",[85,162,163,166,169,173,176,179],{"class":87,"line":119},[85,164,165],{"class":122},"    setUser",[85,167,168],{"class":103},"(",[85,170,172],{"class":171},"s7ZW3","state",[85,174,175],{"class":103},",{",[85,177,178],{"class":171},"user",[85,180,181],{"class":103},"}){\n",[85,183,184,187,190,192,195,198],{"class":87,"line":129},[85,185,186],{"class":99},"            state",[85,188,189],{"class":103},".",[85,191,178],{"class":99},[85,193,194],{"class":103}," =",[85,196,197],{"class":99}," user",[85,199,138],{"class":103},[85,201,203],{"class":87,"line":202},4,[85,204,205],{"class":103},"    }\n",[85,207,209],{"class":87,"line":208},5,[85,210,211],{"class":103},"}\n",[39,213,214],{"id":214},"ミドルェアの作成",[10,216,217,218,221],{},"次に「ログインしたユーザーのみがアクセス可能なページ」を実装できるようにミドルウェアを実装します。",[82,219,220],{},"middleware\u002Fauth.js","を作成します。",[74,223,225],{"className":76,"code":224,"filename":220,"language":79,"meta":80,"style":80},"export default function ({ store, redirect }) {\n    if (!store.state.user) {\n        redirect('\u002Flogin');\n    }\n}\n",[82,226,227,254,280,301,305],{"__ignoreMap":80},[85,228,229,231,234,237,240,243,246,249,252],{"class":87,"line":88},[85,230,92],{"class":91},[85,232,233],{"class":91}," default",[85,235,236],{"class":95}," function",[85,238,239],{"class":103}," ({",[85,241,242],{"class":171}," store",[85,244,245],{"class":103},",",[85,247,248],{"class":171}," redirect",[85,250,251],{"class":103}," })",[85,253,160],{"class":103},[85,255,256,259,261,264,267,269,271,273,275,278],{"class":87,"line":119},[85,257,258],{"class":91},"    if",[85,260,113],{"class":122},[85,262,263],{"class":103},"!",[85,265,266],{"class":99},"store",[85,268,189],{"class":103},[85,270,172],{"class":99},[85,272,189],{"class":103},[85,274,178],{"class":99},[85,276,277],{"class":122},") ",[85,279,116],{"class":103},[85,281,282,286,288,291,295,297,299],{"class":87,"line":129},[85,283,285],{"class":284},"sdLwU","        redirect",[85,287,168],{"class":122},[85,289,290],{"class":103},"'",[85,292,294],{"class":293},"sfyAc","\u002Flogin",[85,296,290],{"class":103},[85,298,135],{"class":122},[85,300,138],{"class":103},[85,302,303],{"class":87,"line":202},[85,304,205],{"class":103},[85,306,307],{"class":87,"line":208},[85,308,211],{"class":103},[10,310,311],{},"単純にStoreのUserステートがnullかどうかでログインページに飛ばすようにしています。",[10,313,314],{},"ページコンポーネントでは以下のようにしてミドルウェアを有効にします。",[74,316,321],{"className":317,"code":318,"filename":319,"language":320,"meta":80,"style":80},"language-vue shiki shiki-themes material-theme-ocean","\u003Ctemplate>\n    \u003Cdiv>\n        auth\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Cscript>\nexport default {\n    name:\"home\",\n    middleware:\"auth\",\n}\n\u003C\u002Fscript>\n","pages\u002Fauth\u002Findex.vue","vue",[82,322,323,334,344,349,358,367,377,386,406,423,428],{"__ignoreMap":80},[85,324,325,328,331],{"class":87,"line":88},[85,326,327],{"class":103},"\u003C",[85,329,330],{"class":122},"template",[85,332,333],{"class":103},">\n",[85,335,336,339,342],{"class":87,"line":119},[85,337,338],{"class":103},"    \u003C",[85,340,341],{"class":122},"div",[85,343,333],{"class":103},[85,345,346],{"class":87,"line":129},[85,347,348],{"class":99},"        auth\n",[85,350,351,354,356],{"class":87,"line":202},[85,352,353],{"class":103},"    \u003C\u002F",[85,355,341],{"class":122},[85,357,333],{"class":103},[85,359,360,363,365],{"class":87,"line":208},[85,361,362],{"class":103},"\u003C\u002F",[85,364,330],{"class":122},[85,366,333],{"class":103},[85,368,370,372,375],{"class":87,"line":369},6,[85,371,327],{"class":103},[85,373,374],{"class":122},"script",[85,376,333],{"class":103},[85,378,380,382,384],{"class":87,"line":379},7,[85,381,92],{"class":91},[85,383,233],{"class":91},[85,385,160],{"class":103},[85,387,389,392,395,398,401,403],{"class":87,"line":388},8,[85,390,391],{"class":122},"    name",[85,393,394],{"class":103},":",[85,396,397],{"class":103},"\"",[85,399,400],{"class":293},"home",[85,402,397],{"class":103},[85,404,405],{"class":103},",\n",[85,407,409,412,414,416,419,421],{"class":87,"line":408},9,[85,410,411],{"class":122},"    middleware",[85,413,394],{"class":103},[85,415,397],{"class":103},[85,417,418],{"class":293},"auth",[85,420,397],{"class":103},[85,422,405],{"class":103},[85,424,426],{"class":87,"line":425},10,[85,427,211],{"class":103},[85,429,431,433,435],{"class":87,"line":430},11,[85,432,362],{"class":103},[85,434,374],{"class":122},[85,436,333],{"class":103},[10,438,439,440,443],{},"こうすることでログインが必要なページを実装することができます。または",[82,441,442],{},"nuxt.config.js"," にて以下のように設定することで全てのページに認証ミドルウェアを適用できます。",[74,445,447],{"className":76,"code":446,"filename":442,"language":79,"meta":80,"style":80},"router: {\n    middleware: 'auth',\n},\n",[82,448,449,459,474],{"__ignoreMap":80},[85,450,451,455,457],{"class":87,"line":88},[85,452,454],{"class":453},"s5Dmg","router",[85,456,394],{"class":103},[85,458,160],{"class":103},[85,460,461,463,465,468,470,472],{"class":87,"line":119},[85,462,411],{"class":453},[85,464,394],{"class":103},[85,466,467],{"class":103}," '",[85,469,418],{"class":293},[85,471,290],{"class":103},[85,473,405],{"class":103},[85,475,476],{"class":87,"line":129},[85,477,478],{"class":103},"},\n",[480,481,483],"h3",{"id":482},"特定のページディレクトリを除く場合","特定のページ、ディレクトリを除く場合",[10,485,486,488],{},[82,487,442],{}," にてグローバルな認証ミドルウェアを実装できますが、未ログインでもアクセス可能なページや、未ログインでないと閲覧できないページ（ログインページなど）では不便です。",[10,490,491,492,495],{},"個別にミドルウェアを作成してページごとに設定してオーバーライドすることも可能ですが、私はよく以下のように",[82,493,494],{},"auth.js","実装しています。",[74,497,499],{"className":76,"code":498,"filename":220,"language":79,"meta":80,"style":80},"\u002F\u002F 特定のページの認証を外す\nexport default function ({ store, redirect }) {\n    if (!store.state.user && route.fullPath !== '\u002Flogin') {\n        redirect('\u002Flogin');\n    }\n}\n",[82,500,501,507,527,569,585,589],{"__ignoreMap":80},[85,502,503],{"class":87,"line":88},[85,504,506],{"class":505},"sC9rS","\u002F\u002F 特定のページの認証を外す\n",[85,508,509,511,513,515,517,519,521,523,525],{"class":87,"line":119},[85,510,92],{"class":91},[85,512,233],{"class":91},[85,514,236],{"class":95},[85,516,239],{"class":103},[85,518,242],{"class":171},[85,520,245],{"class":103},[85,522,248],{"class":171},[85,524,251],{"class":103},[85,526,160],{"class":103},[85,528,529,531,533,535,537,539,541,543,545,548,551,553,556,559,561,563,565,567],{"class":87,"line":129},[85,530,258],{"class":91},[85,532,113],{"class":122},[85,534,263],{"class":103},[85,536,266],{"class":99},[85,538,189],{"class":103},[85,540,172],{"class":99},[85,542,189],{"class":103},[85,544,178],{"class":99},[85,546,547],{"class":103}," &&",[85,549,550],{"class":99}," route",[85,552,189],{"class":103},[85,554,555],{"class":99},"fullPath",[85,557,558],{"class":103}," !==",[85,560,467],{"class":103},[85,562,294],{"class":293},[85,564,290],{"class":103},[85,566,277],{"class":122},[85,568,116],{"class":103},[85,570,571,573,575,577,579,581,583],{"class":87,"line":202},[85,572,285],{"class":284},[85,574,168],{"class":122},[85,576,290],{"class":103},[85,578,294],{"class":293},[85,580,290],{"class":103},[85,582,135],{"class":122},[85,584,138],{"class":103},[85,586,587],{"class":87,"line":208},[85,588,205],{"class":103},[85,590,591],{"class":87,"line":369},[85,592,211],{"class":103},[74,594,596],{"className":76,"code":595,"filename":220,"language":79,"meta":80,"style":80},"\u002F\u002F 特定のディレクトリ配下を外す\nexport default function ({ store, redirect }) {\n    if (!store.state.user && route.fullPath.indexOf('\u002Fpublic') != -1) {\n        redirect('\u002Flogin');\n    }\n}\n",[82,597,598,603,623,679,695,699],{"__ignoreMap":80},[85,599,600],{"class":87,"line":88},[85,601,602],{"class":505},"\u002F\u002F 特定のディレクトリ配下を外す\n",[85,604,605,607,609,611,613,615,617,619,621],{"class":87,"line":119},[85,606,92],{"class":91},[85,608,233],{"class":91},[85,610,236],{"class":95},[85,612,239],{"class":103},[85,614,242],{"class":171},[85,616,245],{"class":103},[85,618,248],{"class":171},[85,620,251],{"class":103},[85,622,160],{"class":103},[85,624,625,627,629,631,633,635,637,639,641,643,645,647,649,651,654,656,658,661,663,665,668,671,675,677],{"class":87,"line":129},[85,626,258],{"class":91},[85,628,113],{"class":122},[85,630,263],{"class":103},[85,632,266],{"class":99},[85,634,189],{"class":103},[85,636,172],{"class":99},[85,638,189],{"class":103},[85,640,178],{"class":99},[85,642,547],{"class":103},[85,644,550],{"class":99},[85,646,189],{"class":103},[85,648,555],{"class":99},[85,650,189],{"class":103},[85,652,653],{"class":284},"indexOf",[85,655,168],{"class":122},[85,657,290],{"class":103},[85,659,660],{"class":293},"\u002Fpublic",[85,662,290],{"class":103},[85,664,277],{"class":122},[85,666,667],{"class":103},"!=",[85,669,670],{"class":103}," -",[85,672,674],{"class":673},"sx098","1",[85,676,277],{"class":122},[85,678,116],{"class":103},[85,680,681,683,685,687,689,691,693],{"class":87,"line":202},[85,682,285],{"class":284},[85,684,168],{"class":122},[85,686,290],{"class":103},[85,688,294],{"class":293},[85,690,290],{"class":103},[85,692,135],{"class":122},[85,694,138],{"class":103},[85,696,697],{"class":87,"line":208},[85,698,205],{"class":103},[85,700,701],{"class":87,"line":369},[85,702,211],{"class":103},[39,704,706],{"id":705},"meリクエストを初期処理にいれる","meリクエストを初期処理にいれる。",[10,708,709,710,713],{},"storeとミドルェアの準備ができたので、APIサーバーに通信をしてユーザー情報を取得するメソッドを作成しておきます。ここではmeリクエストと呼ぶことにします。今回はaxiosで",[82,711,712],{},"https:\u002F\u002Fapi.example.com\u002Fauth\u002Fme","へトークンと一緒にリクエストするとユーザー情報のJSONがレスポンスとして得られるとします。期限切れやトークンがない場合や間違っている場合などは401がレスポンスとして戻ります。",[480,715,717],{"id":716},"spa","SPA",[10,719,720,721,728],{},"SPAの場合は",[722,723,727],"a",{"href":724,"rel":725},"https:\u002F\u002Fgithub.com\u002Fpotato4d\u002Fnuxt-client-init-module",[726],"nofollow","nuxt-client-init-moduleというライブラリ"," を使用するとスムーズです。SSRの場合はNuxtServiceInitという初期処理を実装できるフックがあるのですが、SPAの場合はそれがありあません。Pluginでできなくもないのですが、nuxt-client-init-moduleを使用するとうまくいきやすいです。",[10,730,731],{},"上記のライブラリをインストールしてstoreにてmeリクエストをします。",[74,733,736],{"className":76,"code":734,"filename":735,"language":79,"meta":80,"style":80},"export const actions = {\n  async nuxtClientInit({ commit }, context) {\n    await this.$axios.get('https:\u002F\u002Fapi.example.com\u002Fauth\u002Fme')\n    .then(async res=>{\n        commit('setUser', {user:res.data});\n    })\n    .catch(err=>{\n        console.error(err)\n    })\n  }\n}\n","store\u002Findex.js]",[82,737,738,751,775,802,823,860,867,883,899,905,910],{"__ignoreMap":80},[85,739,740,742,744,747,749],{"class":87,"line":88},[85,741,92],{"class":91},[85,743,96],{"class":95},[85,745,746],{"class":99}," actions ",[85,748,104],{"class":103},[85,750,160],{"class":103},[85,752,753,756,759,762,765,768,771,773],{"class":87,"line":119},[85,754,755],{"class":95},"  async",[85,757,758],{"class":122}," nuxtClientInit",[85,760,761],{"class":103},"({",[85,763,764],{"class":171}," commit",[85,766,767],{"class":103}," },",[85,769,770],{"class":171}," context",[85,772,135],{"class":103},[85,774,160],{"class":103},[85,776,777,780,783,786,788,791,793,795,797,799],{"class":87,"line":129},[85,778,779],{"class":91},"    await",[85,781,782],{"class":103}," this.",[85,784,785],{"class":99},"$axios",[85,787,189],{"class":103},[85,789,790],{"class":284},"get",[85,792,168],{"class":122},[85,794,290],{"class":103},[85,796,712],{"class":293},[85,798,290],{"class":103},[85,800,801],{"class":122},")\n",[85,803,804,807,810,812,815,818,821],{"class":87,"line":202},[85,805,806],{"class":103},"    .",[85,808,809],{"class":284},"then",[85,811,168],{"class":122},[85,813,814],{"class":95},"async",[85,816,817],{"class":171}," res",[85,819,820],{"class":95},"=>",[85,822,116],{"class":103},[85,824,825,828,830,832,835,837,839,842,844,846,849,851,854,856,858],{"class":87,"line":208},[85,826,827],{"class":284},"        commit",[85,829,168],{"class":122},[85,831,290],{"class":103},[85,833,834],{"class":293},"setUser",[85,836,290],{"class":103},[85,838,245],{"class":103},[85,840,841],{"class":103}," {",[85,843,178],{"class":122},[85,845,394],{"class":103},[85,847,848],{"class":99},"res",[85,850,189],{"class":103},[85,852,853],{"class":99},"data",[85,855,132],{"class":103},[85,857,135],{"class":122},[85,859,138],{"class":103},[85,861,862,865],{"class":87,"line":369},[85,863,864],{"class":103},"    }",[85,866,801],{"class":122},[85,868,869,871,874,876,879,881],{"class":87,"line":379},[85,870,806],{"class":103},[85,872,873],{"class":284},"catch",[85,875,168],{"class":122},[85,877,878],{"class":171},"err",[85,880,820],{"class":95},[85,882,116],{"class":103},[85,884,885,888,890,893,895,897],{"class":87,"line":388},[85,886,887],{"class":99},"        console",[85,889,189],{"class":103},[85,891,892],{"class":284},"error",[85,894,168],{"class":122},[85,896,878],{"class":99},[85,898,801],{"class":122},[85,900,901,903],{"class":87,"line":408},[85,902,864],{"class":103},[85,904,801],{"class":122},[85,906,907],{"class":87,"line":425},[85,908,909],{"class":103},"  }\n",[85,911,912],{"class":87,"line":430},[85,913,211],{"class":103},[10,915,916],{},"nuxtClientInitを使用することでページ側の初期化処理より前にユーザー情報を取得できます。",[480,918,920],{"id":919},"ssr","SSR",[10,922,923,924,927],{},"SSRの場合は今度は",[82,925,926],{},"NuxtServiceInit","に変更するだけです。これは特にライブラリは必要なく、SSRであれば利用できます。",[74,929,931],{"className":76,"code":930,"filename":735,"language":79,"meta":80,"style":80},"export const actions = {\n  async NuxtServiceInit({ commit }, context) {\n    \u002F\u002F サーバーサイドでトークンを入れるなどが必要な場合は適宜入れください。\n     await this.$axios.get('https:\u002F\u002Fapi.example.com\u002Fauth\u002Fme')\n    .then(async res=>{\n        commit('setUser', {user:res.data});\n    })\n    .catch(err=>{\n        console.error(err)\n    })\n  }\n}\n",[82,932,933,945,964,969,992,1008,1040,1046,1060,1074,1080,1084],{"__ignoreMap":80},[85,934,935,937,939,941,943],{"class":87,"line":88},[85,936,92],{"class":91},[85,938,96],{"class":95},[85,940,746],{"class":99},[85,942,104],{"class":103},[85,944,160],{"class":103},[85,946,947,949,952,954,956,958,960,962],{"class":87,"line":119},[85,948,755],{"class":95},[85,950,951],{"class":122}," NuxtServiceInit",[85,953,761],{"class":103},[85,955,764],{"class":171},[85,957,767],{"class":103},[85,959,770],{"class":171},[85,961,135],{"class":103},[85,963,160],{"class":103},[85,965,966],{"class":87,"line":129},[85,967,968],{"class":505},"    \u002F\u002F サーバーサイドでトークンを入れるなどが必要な場合は適宜入れください。\n",[85,970,971,974,976,978,980,982,984,986,988,990],{"class":87,"line":202},[85,972,973],{"class":91},"     await",[85,975,782],{"class":103},[85,977,785],{"class":99},[85,979,189],{"class":103},[85,981,790],{"class":284},[85,983,168],{"class":122},[85,985,290],{"class":103},[85,987,712],{"class":293},[85,989,290],{"class":103},[85,991,801],{"class":122},[85,993,994,996,998,1000,1002,1004,1006],{"class":87,"line":208},[85,995,806],{"class":103},[85,997,809],{"class":284},[85,999,168],{"class":122},[85,1001,814],{"class":95},[85,1003,817],{"class":171},[85,1005,820],{"class":95},[85,1007,116],{"class":103},[85,1009,1010,1012,1014,1016,1018,1020,1022,1024,1026,1028,1030,1032,1034,1036,1038],{"class":87,"line":369},[85,1011,827],{"class":284},[85,1013,168],{"class":122},[85,1015,290],{"class":103},[85,1017,834],{"class":293},[85,1019,290],{"class":103},[85,1021,245],{"class":103},[85,1023,841],{"class":103},[85,1025,178],{"class":122},[85,1027,394],{"class":103},[85,1029,848],{"class":99},[85,1031,189],{"class":103},[85,1033,853],{"class":99},[85,1035,132],{"class":103},[85,1037,135],{"class":122},[85,1039,138],{"class":103},[85,1041,1042,1044],{"class":87,"line":379},[85,1043,864],{"class":103},[85,1045,801],{"class":122},[85,1047,1048,1050,1052,1054,1056,1058],{"class":87,"line":388},[85,1049,806],{"class":103},[85,1051,873],{"class":284},[85,1053,168],{"class":122},[85,1055,878],{"class":171},[85,1057,820],{"class":95},[85,1059,116],{"class":103},[85,1061,1062,1064,1066,1068,1070,1072],{"class":87,"line":408},[85,1063,887],{"class":99},[85,1065,189],{"class":103},[85,1067,892],{"class":284},[85,1069,168],{"class":122},[85,1071,878],{"class":99},[85,1073,801],{"class":122},[85,1075,1076,1078],{"class":87,"line":425},[85,1077,864],{"class":103},[85,1079,801],{"class":122},[85,1081,1082],{"class":87,"line":430},[85,1083,909],{"class":103},[85,1085,1087],{"class":87,"line":1086},12,[85,1088,211],{"class":103},[10,1090,1091],{},"NuxtServiceInitというサーバーサイドで上記のリクエストを行って、storeにユーザー情報をいれてくれます。401が来てもcatchしてくれ、ユーザー情報はnullのままになります。",[39,1093,1094],{"id":1094},"完了",[10,1096,1097],{},"エッセンスは以下の通りです。",[55,1099,1100,1103,1106],{},[23,1101,1102],{},"初期処理にユーザー情報を取得するAPIをリクエスト",[23,1104,1105],{},"認証済みであればstoreのuserにユーザー情報のオブジェクトが入る",[23,1107,1108],{},"ミドルウェアやstoreの情報を使用して認証による分岐を行う",[1110,1111,1112],"style",{},"html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s7ZW3, html code.shiki .s7ZW3{--shiki-default:#BABED8;--shiki-default-font-style:italic}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .sC9rS, html code.shiki .sC9rS{--shiki-default:#464B5D;--shiki-default-font-style:italic}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}",{"title":80,"searchDepth":129,"depth":129,"links":1114},[1115,1116,1117,1120,1124],{"id":41,"depth":119,"text":41},{"id":68,"depth":119,"text":69},{"id":214,"depth":119,"text":214,"children":1118},[1119],{"id":482,"depth":129,"text":483},{"id":705,"depth":119,"text":706,"children":1121},[1122,1123],{"id":716,"depth":129,"text":717},{"id":919,"depth":129,"text":920},{"id":1094,"depth":119,"text":1094},[1126],"devstack","2022-05-19","フロント側の認証機能を実装します","md",null,{},true,"\u002Farticles\u002Fnuxt-auth-middleware",{"title":5,"description":1128},"articles\u002Fnuxt-auth-middleware",[1137,1138],"js","nuxt","_common\u002Fnuxt.jpg","MWiO6wSm6JBqm1_bIaWiFdYFIqDsWKtpAvMLHvfsPGg",1780987143974]