APIリクエスト送信ボタンクリック時に、401 (Unauthorized)が返ってくる
JWTキーを使用してログインを管理するための機能を実装。
import axios from 'axios'
// APIのベースURLを設定したインスタンスを作成
const api = axios.create({
baseURL: 'http://localhost:8080/v1', //全てのAPIのプレフィックス
headers: {
'Content-Type': 'application/json',
// 初期化時にlocalStorageからトークンを読み込む
Authorization: localStorage.getItem('jwtToken')
? `Bearer ${localStorage.getItem('jwtToken')}`
: undefined,
},
})
// ログイン成功後にヘッダーを更新
export const setAuthHeader = (token: string | null) => {
if (token) {
api.defaults.headers.common['Authorization'] = `Bearer ${token}`
} else {
delete api.defaults.headers.common['Authorization']
}
}
// レスポンスインターセプター: エラー共通処理
api.interceptors.response.use(
(Response) => Response,
(error) => {
// 401エラーの場合、自動でログアウト処理などに誘導
if (error.response && error.response.status === 401) {
console.error('認証エラー:トークンをリフレッシュするか、ログインが必要です。')
// 後にrouter.push('/login')などのロジック追加
}
return Promise.reject(error)
},
)
export default api
ログイン後、JWTトークンを発行。ユーザによりAPIリクエストが実行されると、DBに保存される。
というのが理想だけど、401エラーが返ってくる。という無限ループにハマった。
以下、私の解決策です。
※赤文字が今回の問題のコード
エラー内容
- POST http://localhost:8080/v1/character-create 401 (Unauthorized)
- api.ts:30 認証エラー:トークンをリフレッシュするか、ログインが必要です。
- AxiosError {message: 'Request failed with status code 401', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
ログイン後、1分も立たずにトークンが無くなるってそんなわけあるか。
その他確認事項
- jwtキーがログイン時に発行されるも、APIリクエスト送信時に消える。(devtoolのApplicationタブを確認)
- request headerにauthorizationが存在しない(devtoolのNetworkタブを確認)
結論
初期化時のAuthorizationヘッダー設定を削除し、初期化前にヘッダー設定を行う。
import axios from 'axios'
// APIのベースURLを設定したインスタンスを作成
const api = axios.create({
baseURL: 'http://localhost:8080/v1', //全てのAPIのプレフィックス
headers: {
'Content-Type': 'application/json',
},
})
// すべてのリクエスト送信直前に実行されるインターセプターを設定
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('jwtToken')
// トークンが存在する場合のみヘッダーを設定
if (token) {
config.headers.Authorization = `Bearer ${token}`
} else {
// トークンがない場合はAuthorizationヘッダーを削除(または設定しない)
delete config.headers.Authorization
}
return config
},
(error) => {
return Promise.reject(error)
},
)
// レスポンスインターセプター: エラー共通処理
api.interceptors.response.use(
(Response) => Response,
(error) => {
// 401エラーの場合、自動でログアウト処理などに誘導
if (error.response && error.response.status === 401) {
console.error('認証エラー:トークンをリフレッシュするか、ログインが必要です。')
// 後にrouter.push('/login')などのロジック追加
}
return Promise.reject(error)
},
)
export default api
原因
- アプリ起動時(初期化時)にlocalstrageを確認。初回起動なのでjwtToken無し。
- ログイン直後のAPIコールでjwtTokenを発行し、ヘッダーにAuthorizationを追加。localstrageに格納。
- APIリクエスト送信時、再初期化が実行される。
- 初期化時にlocalstrageを確認。初期化後の為headerにはAuthorizationがいない。
- 401 (Unauthorized)エラー
というアンジャッシュネタロジックだった。
初期化前(リクエスト送信直前)にlocalstrageを確認して、headerを設定して完了。

“APIリクエスト送信ボタンクリック時に、401 (Unauthorized)が返ってくる” に対して1件のコメントがあります。