![見出し画像](https://assets.st-note.com/production/uploads/images/95324089/rectangle_large_type_2_4a485934cadea24e120b07c3fdd0c038.png?width=800)
Fetch APIからbearer tokenで認証する時の正しい渡し方に迷う
Fetch APIでのbearer tokenの渡し方について
▼ こういう場面で必要になる
認証が必要なRest APIを呼び出す場合
Rest APIにJWTを渡したい場合
あるいは自分でRest APIを作ってる場合
僕の場合は最後のケースに当てはまります。
Node.js + ExpressでRest API的なのを作ってた時です。
▼ こういうRest APIを作った
JSONを返すGETメソッド
JWTによるユーザー認証が必要
※ JWT = JSON Web Token
それでFetch APIから自作のRest APIを呼び出しました
これが動いてくれなくて困ります。
何度やっても401エラーが返ってくるみたいな感じ
試行錯誤の上で分かったことを書き留めます。
最初にこういうqiitaの記事を見つけた
ググって解決策を探しました。
▼ こういうqiitaの記事を見つけた
オプションのheadersフィールドにHeadersオブジェクトもしくはJSONでHTTPリクエストヘッダの内容を指定することができます。
fetch('https://www.googleapis.com/userinfo/v2/me', {
headers: { 'Authorization': 'Bearer: (アクセストークン)' }
}).then(function(response) {
return response.json();
}).then(function(json) {
...
});
ヘッダーに Authorization を指定すればいいみたいです。
▼ こういうコードを書いてみたが…
const TOKEN = '【任意のJSON Web Token】';
fetch('/api/test'
{
method: 'GET',
headers: {
'Authorization': 'Bearer: '+TOKEN,
'Content-Type': 'application/json',
}
}
).then(async (response)=>{
console.log('response : ', response);
console.log('json : ', await response.json());
}).then((data)=>{
console.log('data : ', data);
}).catch((error) => {
console.error('error : ', error);
});
▼ 返ってきたレスポンスの一部
ok : false
redirected : false
status : 401
statusText : "Unauthorized"
type : "basic"
トークン自体に誤りはないのに "Unauthorized" が出てしまう
さらに別の記事書いてある方法も試したが…
さらにググって別の記事を見つけました。
▼ Sending Requests Using JavaScript Fetch API
You can pass HTTP headers to the fetch() request as the second parameter. For example, to pass the Bearer Token Authorization Header, call fetch() with the {headers: {Authentication: 'Bearer Token'}} parameter.
Fetch API Request with Bearer Token Authorization Header
fetch('https://reqbin.com/echo/get/json', {
headers: {Authentication: 'Bearer Token'}
})
.then(resp => resp.json())
.then(json => console.log(json))
Qiitaの記事だと 'Authorization' というフィールド名だったけど、
こっちの記事だと 'Authentication' という名前になってます。
どっちが正しいのか分からず困惑
あと Bearer のあとのコロン(:)はいらないみたいです。
そこでこの記事を参考にコードを書きなおしました。
▼ このようなコードを書いたが…
const TOKEN = '【任意のJSON Web Token】';
fetch('/api/test'
{
method: 'GET',
headers: {
'Authentication': 'Bearer '+TOKEN,
'Content-Type': 'application/json',
}
}
).then(async (response)=>{
console.log('response : ', response);
console.log('json : ', await response.json());
}).then((data)=>{
console.log('data : ', data);
}).catch((error) => {
console.error('error : ', error);
});
▼ 返ってきたレスポンスの一部
ok : false
redirected : false
status : 401
statusText : "Unauthorized"
type : "basic"
やっぱり401エラーでユーザー認証がうまくいきません。
それぞれの記事は部分的に間違いがあるみたいです。
結局 'Authorization': 'Bearer …' が正解だった
ということで最終的に答えを見つけました。
Authorizationフィールドを使う
'Bearer ' の後にトークンを渡す
Fetch APIだけではなくCurlによるリクエストでも同じです。
次のようなコードを試したら期待通りになりました。
▼ このコードでユーザー認証成功
const TOKEN = '【任意のJSON Web Token】';
fetch('/api/test'
{
method: 'GET',
headers: {
'Authorization': 'Bearer '+TOKEN,
'Content-Type': 'application/json',
}
}
).then(async (response)=>{
console.log('response : ', response);
console.log('json : ', await response.json());
}).then((data)=>{
console.log('data : ', data);
}).catch((error) => {
console.error('error : ', error);
});
この仕様はNode.js + Expressだけに限らず、
Laravelとかで認証付きRest APIを作った場合も同じはずです。
これだけのことなのに、分からないと少し困惑します。
ググった情報も疑うことが大事(教訓)
この記事が気に入ったらサポートをしてみませんか?