'React Native Image with 'Bearer' authentication token
In React Native I can use images with <Image source={{uri: 'http://my.server.com/user/id/image/id.png'}} />
The problem is that user images are protected by JWT token which I pass in the header.
Is it possible to somehow include that additional header?
What are my other options?
Thanks!
Solution 1:[1]
Your options are this one: https://rnplay.org/apps/UowZmw (in order to see the simulator, type document.querySelector('.editor-container').style.width = '50%'
in dev console, RNPlay is a bit broken with lengthy content).
Basically what you do is to:
1. serve your images as blobs
2. fetch them with fetch()
to the app.
3. use base64 data as content of uri
property
Do this in your componentWillMount()
:
fetch(YOUR_IMAGE_URI, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + 'TOKEN'
}
}
).then((res) => res.text())
.then((content) => {
this.setState({
base64: content
})
})
You may notice I use res.text()
instead of res.blob()
. This is because, while writing this, RN doesn't support .blob().
And this goes to render()
:
return (
<Image style={styles.base64} source={{uri: this.state.base64}} />
)
Solution 2:[2]
You can send headers in the source prop.
<Image
source={
{ uri: 'https://yourdomain.com/get-image',
headers: {
Authorization: 'Bearer xyz'
}
}
}/>
you can specify other parameters as well: ImageSourcePropType.js
Solution 3:[3]
For me the answer from blink281 didn't work. It seems this is a common Android problem according to this thread https://github.com/facebook/react-native/issues/25945 and while writing this it's not fixxed. I was looking for another solution and the answer from Samuli Hakoniemi helped me build one, so i wanted to share a fully working example as his Link is not working anymore.
I created an external Component called NetworkImage for this.
import React from "react";
import { StyleSheet, View, Image } from "react-native";
class NetworkImage extends React.Component {
constructor(props) {
super(props);
this.state = {
base64: null,
};
this.style = props.style;
this.imageId = props.imageId;
this.token = props.token;
}
componentDidMount() {
var imageUri = "/auth/diary/image/" + this.imageId;
fetch(imageUri, {
method: "GET",
headers: {
Pragma: "no-cache",
"x-access-token": this.token,
},
redirect: "follow",
})
.then((res) => res.text())
.then((content) => {
let data =
"data:image/jpeg;base64," +
content.substring(1, content.length - 1);
this.setState({
base64: data,
});
});
});
}
render() {
return <Image style={this.style} source={{ uri: this.state.base64 }} />;
}
}
export default NetworkImage;
In this case i had to prepend "data:image/jpeg;base64," because the data i got is raw without the datatype.
Solution 4:[4]
import RNFetchBlob from "rn-fetch-blob";
const { config, fs } = RNFetchBlob;
let PictureDir = fs.dirs.PictureDir;
let date = new Date();
let options = {
fileCache: true,
addAndroidDownloads: {
//Related to the Android only
useDownloadManager: true,
notification: true,
path:
PictureDir +
"/Report_Download" +
Math.floor(date.getTime() + date.getSeconds() / 2),
description: "Risk Report Download",
},
};
config(options)
.fetch('GET', url, {
Authorization: token,
})
// when response status code is 200
.then((res) => {
// the conversion is done in native code
console.log(JSON.stringify(res));
alert('report download successfully')
})
// Status code is not 200
.catch((errorMessage, statusCode) => {
// error handling
console.log('errorMessage', errorMessage);
console.log('statusCode', statusCode);
})
that's all. enjoy your coding...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | blink281 |
Solution 3 | Dharman |
Solution 4 | mahendren |