質問編集履歴

5

参考サイトを追記

2018/06/21 02:52

投稿

tarotarosu
tarotarosu

スコア114

test CHANGED
File without changes
test CHANGED
@@ -317,3 +317,13 @@
317
317
  という手法です。
318
318
 
319
319
  この手法を実現する方法はないでしょうか?...
320
+
321
+
322
+
323
+
324
+
325
+ 下記リンク先で同じ疑問を持った方がいるようなのですが、回答にあるようなセキュリティルールでは誰でもアクセスできてしまうので...
326
+
327
+
328
+
329
+ [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

2018/06/21 02:51

投稿

tarotarosu
tarotarosu

スコア114

test CHANGED
File without changes
test CHANGED
@@ -275,3 +275,45 @@
275
275
  を利用して画像を表示させようとしていることに問題があるのではないかと思っています。
276
276
 
277
277
  (末尾のトークン(?)を省いているのが原因なのかどうなのか...)
278
+
279
+
280
+
281
+ ### 追記2_1
282
+
283
+ ダウンロードURLの末尾のトークンを省いていることに問題がありそうだったので、
284
+
285
+
286
+
287
+ ```javascript
288
+
289
+ downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media&token=hogehoge...`
290
+
291
+ ```
292
+
293
+
294
+
295
+ のように(コンソールから確認できるダウンロードURLで)記述したところ、認証状態によって画像の表示・非表示ができました。
296
+
297
+ (ただこのトークンが何なのかを今一つ理解せずに実験してみての結果なのでトークンによるものなのかは断言できないです...)
298
+
299
+
300
+
301
+ しかし、末尾のトークンを正しくつけてやればいいのではないかということは分かったのですが、個人的に考える重大な問題があります。
302
+
303
+ それは「ダウンロードURLを`<img>`に突っ込んでいるわけなので、ブラウザのディベロッパツールなどからダウンロードURLを見れば、簡単に外部からでもアクセスできてしまう」というものです。
304
+
305
+ ユーザ認証をパスした者が悪意あるユーザにダウンロードURLを教えた場合、そのダウンロードURLにアクセスしまくり、Firebaseの料金に影響を及ぼすことはできるわけですよね?
306
+
307
+
308
+
309
+ ちなみにですが、末尾のトークンを含まないダウンロードURLで外部からアクセスした場合は403が返ってき、アクセスできません。
310
+
311
+
312
+
313
+ なので理想としては、
314
+
315
+ 「ユーザ認証をパスしたユーザにのみCloud Storage上の画像を表示させる。しかも画像を表示させるためのダウンロードURLは末尾のトークンを抜いた形式で」
316
+
317
+ という手法です。
318
+
319
+ この手法を実現する方法はないでしょうか?...

3

試したことを追記

2018/06/21 02:10

投稿

tarotarosu
tarotarosu

スコア114

test CHANGED
File without changes
test CHANGED
@@ -223,3 +223,55 @@
223
223
  });
224
224
 
225
225
  ```
226
+
227
+
228
+
229
+ ### 追記2
230
+
231
+
232
+
233
+ 色々と試しているのですが、下記のように`getDownloadURL()`を使って画像のダウンロードURLを取得し、表示させようとすると、ちゃんとユーザの認証状態によって画像の表示・非表示ができます。
234
+
235
+
236
+
237
+ ```javascript
238
+
239
+ const storage = firebase.storage();
240
+
241
+ const fileRef = storage.ref().child('path to file');
242
+
243
+ fileRef.getDownloadURL().then((url) => {
244
+
245
+ this.setState({
246
+
247
+ downloadUrl: url,
248
+
249
+ });
250
+
251
+ }).catch((err) => {
252
+
253
+ console.log(err);
254
+
255
+ });
256
+
257
+ ```
258
+
259
+
260
+
261
+ つまり、`getDownloadURL()`で画像を表示せずに、
262
+
263
+ Firestoreに記述された
264
+
265
+
266
+
267
+ ```javascript
268
+
269
+ downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media`
270
+
271
+ ```
272
+
273
+
274
+
275
+ を利用して画像を表示させようとしていることに問題があるのではないかと思っています。
276
+
277
+ (末尾のトークン(?)を省いているのが原因なのかどうなのか...)

2

誤字修正

2018/06/21 00:58

投稿

tarotarosu
tarotarosu

スコア114

test CHANGED
File without changes
test CHANGED
@@ -178,7 +178,7 @@
178
178
 
179
179
 
180
180
 
181
- そして、`uid`が表示できた場合に表示するコンポーネントの中で、
181
+ そして、`uid`が取得できた場合に表示するコンポーネントの中で、
182
182
 
183
183
 
184
184
 

1

コメントを受けての追記

2018/06/20 13:30

投稿

tarotarosu
tarotarosu

スコア114

test CHANGED
File without changes
test CHANGED
@@ -77,3 +77,149 @@
77
77
  ユーザ認証をパスしているはずなのになぜ画像が表示できなくなってしまったのでしょうか?
78
78
 
79
79
  何かご回答を頂けると助かります<(_ _)>
80
+
81
+
82
+
83
+ ### 追記
84
+
85
+ Reactのコードですが、
86
+
87
+ ユーザ認証を行う下記コンポーネント内で`uid`が取得出来たら配下のコンポーネントを表示し、取得できなければログインページへリダイレクトさせるという処理をし確認しています。
88
+
89
+
90
+
91
+ ```jsx
92
+
93
+ export default class Auth extends React.Component {
94
+
95
+ constructor(props) {
96
+
97
+ super(props);
98
+
99
+ this.state = {
100
+
101
+ uid: null,
102
+
103
+ loading: true,
104
+
105
+ };
106
+
107
+ }
108
+
109
+
110
+
111
+ componentDidMount() {
112
+
113
+ this.removeListener = firebase.auth().onAuthStateChanged((user) => {
114
+
115
+ if (user) {
116
+
117
+ this.setState({
118
+
119
+ uid: user.uid,
120
+
121
+ loading: false,
122
+
123
+ });
124
+
125
+ } else {
126
+
127
+ this.setState({
128
+
129
+ loading: false,
130
+
131
+ });
132
+
133
+ }
134
+
135
+ });
136
+
137
+ }
138
+
139
+
140
+
141
+ render() {
142
+
143
+ if (this.state.loading) {
144
+
145
+ return (
146
+
147
+ <p>Now Loading...</p>
148
+
149
+ );
150
+
151
+ }
152
+
153
+
154
+
155
+ if (!this.state.uid) {
156
+
157
+ return (
158
+
159
+ <Redirect to="/" />
160
+
161
+ );
162
+
163
+ }
164
+
165
+
166
+
167
+ return (
168
+
169
+ this.props.children
170
+
171
+ );
172
+
173
+ }
174
+
175
+ }
176
+
177
+ ```
178
+
179
+
180
+
181
+ そして、`uid`が表示できた場合に表示するコンポーネントの中で、
182
+
183
+
184
+
185
+ ```javascript
186
+
187
+ downloadUrl: `https://firebasestorage.googleapis.com/v0/b/${bucketName}/o/${encodeURIComponent(filePath)}?alt=media`
188
+
189
+ ```
190
+
191
+
192
+
193
+ が格納されたFirestoreのドキュメントを下記のようにまとめて取得し、`<img>`に突っ込んでいっています。
194
+
195
+
196
+
197
+ ```javascript
198
+
199
+ const db = firebase.firestore();
200
+
201
+ const datas = [];
202
+
203
+
204
+
205
+ db.collection('images').get()
206
+
207
+ .then((snapshot) => {
208
+
209
+ snapshot.forEach((doc) => {
210
+
211
+ const data = doc.data();
212
+
213
+ datas.push(data);
214
+
215
+ });
216
+
217
+ this.setState({
218
+
219
+ imageDatas: datas,
220
+
221
+ });
222
+
223
+ });
224
+
225
+ ```