'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