質問編集履歴
5
参考サイトを追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -157,4 +157,9 @@
|
|
157
157
|
なので理想としては、
|
158
158
|
「ユーザ認証をパスしたユーザにのみCloud Storage上の画像を表示させる。しかも画像を表示させるためのダウンロードURLは末尾のトークンを抜いた形式で」
|
159
159
|
という手法です。
|
160
|
-
この手法を実現する方法はないでしょうか?...
|
160
|
+
この手法を実現する方法はないでしょうか?...
|
161
|
+
|
162
|
+
|
163
|
+
下記リンク先で同じ疑問を持った方がいるようなのですが、回答にあるようなセキュリティルールでは誰でもアクセスできてしまうので...
|
164
|
+
|
165
|
+
[Access url without token in Firebase Storage - Stack Overflow](https://stackoverflow.com/questions/46153828/access-url-without-token-in-firebase-storage?rq=1)
|
4
追記2_1
title
CHANGED
File without changes
|
body
CHANGED
@@ -136,4 +136,25 @@
|
|
136
136
|
```
|
137
137
|
|
138
138
|
を利用して画像を表示させようとしていることに問題があるのではないかと思っています。
|
139
|
-
(末尾のトークン(?)を省いているのが原因なのかどうなのか...)
|
139
|
+
(末尾のトークン(?)を省いているのが原因なのかどうなのか...)
|
140
|
+
|
141
|
+
### 追記2_1
|
142
|
+
ダウンロードURLの末尾のトークンを省いていることに問題がありそうだったので、
|
143
|
+
|
144
|
+
```javascript
|
145
|
+
downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media&token=hogehoge...`
|
146
|
+
```
|
147
|
+
|
148
|
+
のように(コンソールから確認できるダウンロードURLで)記述したところ、認証状態によって画像の表示・非表示ができました。
|
149
|
+
(ただこのトークンが何なのかを今一つ理解せずに実験してみての結果なのでトークンによるものなのかは断言できないです...)
|
150
|
+
|
151
|
+
しかし、末尾のトークンを正しくつけてやればいいのではないかということは分かったのですが、個人的に考える重大な問題があります。
|
152
|
+
それは「ダウンロードURLを`<img>`に突っ込んでいるわけなので、ブラウザのディベロッパツールなどからダウンロードURLを見れば、簡単に外部からでもアクセスできてしまう」というものです。
|
153
|
+
ユーザ認証をパスした者が悪意あるユーザにダウンロードURLを教えた場合、そのダウンロードURLにアクセスしまくり、Firebaseの料金に影響を及ぼすことはできるわけですよね?
|
154
|
+
|
155
|
+
ちなみにですが、末尾のトークンを含まないダウンロードURLで外部からアクセスした場合は403が返ってき、アクセスできません。
|
156
|
+
|
157
|
+
なので理想としては、
|
158
|
+
「ユーザ認証をパスしたユーザにのみCloud Storage上の画像を表示させる。しかも画像を表示させるためのダウンロードURLは末尾のトークンを抜いた形式で」
|
159
|
+
という手法です。
|
160
|
+
この手法を実現する方法はないでしょうか?...
|
3
試したことを追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -110,4 +110,30 @@
|
|
110
110
|
imageDatas: datas,
|
111
111
|
});
|
112
112
|
});
|
113
|
-
```
|
113
|
+
```
|
114
|
+
|
115
|
+
### 追記2
|
116
|
+
|
117
|
+
色々と試しているのですが、下記のように`getDownloadURL()`を使って画像のダウンロードURLを取得し、表示させようとすると、ちゃんとユーザの認証状態によって画像の表示・非表示ができます。
|
118
|
+
|
119
|
+
```javascript
|
120
|
+
const storage = firebase.storage();
|
121
|
+
const fileRef = storage.ref().child('path to file');
|
122
|
+
fileRef.getDownloadURL().then((url) => {
|
123
|
+
this.setState({
|
124
|
+
downloadUrl: url,
|
125
|
+
});
|
126
|
+
}).catch((err) => {
|
127
|
+
console.log(err);
|
128
|
+
});
|
129
|
+
```
|
130
|
+
|
131
|
+
つまり、`getDownloadURL()`で画像を表示せずに、
|
132
|
+
Firestoreに記述された
|
133
|
+
|
134
|
+
```javascript
|
135
|
+
downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media`
|
136
|
+
```
|
137
|
+
|
138
|
+
を利用して画像を表示させようとしていることに問題があるのではないかと思っています。
|
139
|
+
(末尾のトークン(?)を省いているのが原因なのかどうなのか...)
|
2
誤字修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -88,7 +88,7 @@
|
|
88
88
|
}
|
89
89
|
```
|
90
90
|
|
91
|
-
そして、`uid`が
|
91
|
+
そして、`uid`が取得できた場合に表示するコンポーネントの中で、
|
92
92
|
|
93
93
|
```javascript
|
94
94
|
downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media`
|
1
コメントを受けての追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -37,4 +37,77 @@
|
|
37
37
|
このようなセキュリティルールに書き換えたところ、ユーザ認証をパスしたユーザであっても画像を表示できなくなってしまいました(403エラーが返ってきます)。
|
38
38
|
|
39
39
|
ユーザ認証をパスしているはずなのになぜ画像が表示できなくなってしまったのでしょうか?
|
40
|
-
何かご回答を頂けると助かります<(_ _)>
|
40
|
+
何かご回答を頂けると助かります<(_ _)>
|
41
|
+
|
42
|
+
### 追記
|
43
|
+
Reactのコードですが、
|
44
|
+
ユーザ認証を行う下記コンポーネント内で`uid`が取得出来たら配下のコンポーネントを表示し、取得できなければログインページへリダイレクトさせるという処理をし確認しています。
|
45
|
+
|
46
|
+
```jsx
|
47
|
+
export default class Auth extends React.Component {
|
48
|
+
constructor(props) {
|
49
|
+
super(props);
|
50
|
+
this.state = {
|
51
|
+
uid: null,
|
52
|
+
loading: true,
|
53
|
+
};
|
54
|
+
}
|
55
|
+
|
56
|
+
componentDidMount() {
|
57
|
+
this.removeListener = firebase.auth().onAuthStateChanged((user) => {
|
58
|
+
if (user) {
|
59
|
+
this.setState({
|
60
|
+
uid: user.uid,
|
61
|
+
loading: false,
|
62
|
+
});
|
63
|
+
} else {
|
64
|
+
this.setState({
|
65
|
+
loading: false,
|
66
|
+
});
|
67
|
+
}
|
68
|
+
});
|
69
|
+
}
|
70
|
+
|
71
|
+
render() {
|
72
|
+
if (this.state.loading) {
|
73
|
+
return (
|
74
|
+
<p>Now Loading...</p>
|
75
|
+
);
|
76
|
+
}
|
77
|
+
|
78
|
+
if (!this.state.uid) {
|
79
|
+
return (
|
80
|
+
<Redirect to="/" />
|
81
|
+
);
|
82
|
+
}
|
83
|
+
|
84
|
+
return (
|
85
|
+
this.props.children
|
86
|
+
);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
```
|
90
|
+
|
91
|
+
そして、`uid`が表示できた場合に表示するコンポーネントの中で、
|
92
|
+
|
93
|
+
```javascript
|
94
|
+
downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media`
|
95
|
+
```
|
96
|
+
|
97
|
+
が格納されたFirestoreのドキュメントを下記のようにまとめて取得し、`<img>`に突っ込んでいっています。
|
98
|
+
|
99
|
+
```javascript
|
100
|
+
const db = firebase.firestore();
|
101
|
+
const datas = [];
|
102
|
+
|
103
|
+
db.collection('images').get()
|
104
|
+
.then((snapshot) => {
|
105
|
+
snapshot.forEach((doc) => {
|
106
|
+
const data = doc.data();
|
107
|
+
datas.push(data);
|
108
|
+
});
|
109
|
+
this.setState({
|
110
|
+
imageDatas: datas,
|
111
|
+
});
|
112
|
+
});
|
113
|
+
```
|