GithubHelp home page GithubHelp logo

Comments (28)

justin808 avatar justin808 commented on July 23, 2024 1

This is probably the one we want to to support:

https://github.com/matthew-andrews/isomorphic-fetch

from react_on_rails.

anpr avatar anpr commented on July 23, 2024 1

I'd be happy to have this as part of react_on_rails. It's really a very common requirement.

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024 1

@anpr I think part of the standard npm package for react-on-rails is fine if it's very small.

from react_on_rails.

dphaener avatar dphaener commented on July 23, 2024

My two cents. I use this:

import _ from 'underscore'

/* globals document */

export default class BaseData {
  constructor() {
    this.defaultParams = {
      credentials: 'same-origin'
    }
  }

  getCSRFToken() {
    return _.find(document.getElementsByTagName("meta"), (meta) => {
      return meta.name === "csrf-token"
    }).content
  }

  defaultHeaders = () => {
    return {
      'X-CSRF-Token': this.getCSRFToken(),
      'Accept': 'application/vnd.api+json',
      'Content-Type': 'application/vnd.api+json'
    }
  }

  post = (url, props) => {
    return fetch(url, {
      method: 'post',
      headers: this.defaultHeaders(),
      body: JSON.stringify(props),
      ...this.defaultParams
    })
    .then((response) => {
      return response.json()
    })
  }

  put = (url, props) => {
    return fetch(url, {
      method: 'put',
      headers: this.defaultHeaders(),
      body: JSON.stringify(props),
      ...this.defaultParams
    })
    .then((response) => {
      return response.json()
    })
  }

  delete = (url) => {
    return fetch(url, {
      method: 'delete',
      headers: this.defaultHeaders(),
      ...this.defaultParams
    })
    .then((response) => {
      return response.json()
    })
  }
}

And this module: "whatwg-fetch": "^0.9.0"

And in the webpack config:

new webpack.ProvidePlugin({
      'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
    })

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

We're using axios here:

https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/package.json

@alexfedoseev Are we missing the headers for:

     'Accept': 'application/vnd.api+json',
      'Content-Type': 'application/vnd.api+json'

Here's our source: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client%2Fapp%2Futils%2FcommentsManager.js

import request from 'axios';

const API_URL = 'comments.json';

const CommentsManager = {

  /**
   * Retrieve comments from server using AJAX call.
   *
   * @returns {Promise} - result of ajax call.
   */
  fetchComments() {
    return request({
      method: 'GET',
      url: API_URL,
      responseType: 'json',
    });
  },

  /**
   * Submit new comment to server using AJAX call.
   *
   * @param {Object} comment - Comment body to post.
   * @returns {Promise} - result of ajax call.
   */
  submitComment(comment) {
    return request({
      method: 'POST',
      url: API_URL,
      responseType: 'json',
      headers: {
        'X-CSRF-Token': this.getCSRFToken(),
      },
      data: { comment },
    });
  },

  /**
   * Get CSRF Token from the DOM.
   *
   * @returns {String} - CSRF Token.
   */
  getCSRFToken() {
    const metas = document.getElementsByTagName('meta');
    for (let i = 0; i < metas.length; i++) {
      const meta = metas[i];
      if (meta.getAttribute('name') === 'csrf-token') {
        return meta.getAttribute('content');
      }
    }

    return null;
  },

};

export default CommentsManager;

from react_on_rails.

alex35mil avatar alex35mil commented on July 23, 2024

Are we missing the headers for

No, since we don't use Vendor MIME Type to match the api version (we use URL instead).
More on subject: https://medium.com/@alexfedoseev/isomorphic-react-with-rails-part-ii-614980b65aef

And example of apiCall helper with axios:

import http from 'axios';
import getCSRFToken from './getCSRFToken';

const apiURLPrefix = '/api/v1';

// Transforming Immutable data to plain JS
http.defaults.transformRequest.unshift(data => (
  data && data.toJS === 'function' ? data.toJS() : data
));

http.interceptors.request.use(config => {
  // If it's not remote call, adding api prefix
  if (!config.remote) {
    config.url = `${apiURLPrefix}${config.url}`;
  }

  // Adding CSRF Token header
  config.headers = {
    'X-CSRF-Token': getCSRFToken(),
  };
  return config;
});

export default params => http(params);

from react_on_rails.

dphaener avatar dphaener commented on July 23, 2024

👍 I'm using that because I'm using a jsonapi-resources backend, which requires that MIME type

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

@alexfedoseev @josiasds @mapreal19 How about we release a tiny npm module to encapsulation axios and the ability to get the CRSF token from Rails? Then we can put the inclusion of the tiny npm module in the template setup.

from react_on_rails.

alex35mil avatar alex35mil commented on July 23, 2024

I'd rather made getCRSFToken module and left axios in user land.

Reasons:

  1. axios is opinionated.
  2. axios's setup is opinionated.

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

@jbhatab @alexfedoseev Once we put in the NPM library, I'll try to merge in the code from the: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/libs/metaTagsManager.js

from react_on_rails.

robwise avatar robwise commented on July 23, 2024

@justin808 @alexfedoseev @jbhatab

Regardless though, I vote we do not put this in the npm module for the same reason that Alex chose not to use Axios's implementation. Some people may not even be doing sessions this way.

from react_on_rails.

rescribet avatar rescribet commented on July 23, 2024

Just to leave another implementation here for the sake of brainstorm. We only use helper methods that don't wrap fetch, but aid in parameter setting. Implementation in this gist.

For regular non-safe json requests:

fetch('/foobar.json', jsonHeader(/*fetch options*/));

With just the Rails CSRF headers:

fetch('/foobar.json', authenticityHeader(/*fetch options*/));

For safe calls (includes CSRF and credentials & same-origin header):

fetch('/foobar.json', safeCredentials(/*fetch options*/));

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

We'll soon be adding a JS helper method for the CRSF to the ReactOnRails npm module for this.

We probably want to be agnostic about the choice of fetch vs. axios.

from react_on_rails.

robwise avatar robwise commented on July 23, 2024

agreed

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

We simply need to add this helper method to ReactOnRails.

From: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/libs/metaTagsManager.js

import _ from 'lodash';

export default {

  /**
   * Get CSRF Token from the DOM.
   *
   * @returns {String} - CSRF Token.
   */
  getCSRFToken() {
    const token = _.find(document.querySelectorAll('meta'), ['name', 'csrf-token']);
    return token ? token.content : null;
  },

};

To:

We should also remove the dependency on lodash.

We need some docs and tests.

This gist from @fletcher91 also looks good: https://gist.github.com/fletcher91/c62b865c6aa9f710531e

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

I'll probably add @fletcher91's code to the default package for ReactOnRails. Yes, we could have a separate node module. It's a tiny enough amount of code that I don't deem that necessary.

@fletcher91 Any changes to your gist? I copied below.

/**
 * 
 * A regular non-safe get request:
 * fetch('/profiles/foobar.json', jsonHeader());
 * 
 * How this would look in a safe fetch request:
 * fetch('/profiles.json', safeCredentials({
 *              method: 'POST',
 *              body: JSON.stringify({
 *                  q: input,
 *                  thing: this.props.thing
 *              })
 *          }));
 *
 * 
 */

/**
 * For use with window.fetch
 */
export function jsonHeader (options) {
    options = options || {};
    return Object.assign(options, {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    });
}

/**
 * Lets fetch include credentials in the request. This includes cookies and other possibly sensitive data.
 * Note: Never use for requests across (untrusted) domains.
 */
export function safeCredentials (options) {
    options = options || {};
    return Object.assign(options, {
        credentials: 'include',
        mode: 'same-origin',
        headers: Object.assign((options['headers'] || {}), authenticityHeader(), jsonHeader())
    });
}

// Additional helper methods

export function authenticityHeader (options) {
    options = options || {};
    return Object.assign(options, {
        'X-CSRF-Token': getAuthenticityToken(),
        'X-Requested-With': 'XMLHttpRequest'
    });
}

export function getAuthenticityToken () {
    return getMetaContent('csrf-token');
}

export function getMetaContent (name) {
    let header = document.querySelector(`meta[name="${name}"]`);
    return header && header.content;
}

from react_on_rails.

rescribet avatar rescribet commented on July 23, 2024

@justin808 Aside from some minor things like let to const and some JSdocs, it's still the same 👍 I've updated the gist accordingly

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

@fletcher91, @jbhatab does this make sense to go into React on Rails from the perspective that the CRSF thing is so standard for Rails apps? or more of a doc thing?

from react_on_rails.

jbhatab avatar jbhatab commented on July 23, 2024

@anpr With the direction were going, I think this shouldn't be covered with our gem and can be covered in a docs if even needed at all. it depends on your architecture style.

We can relook into this when we redo the docs stuff.

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

@jbhatab, we're going to provide a default for this. I really think this is so common that it makes sense to include in our library, if it's non-obtrusive.

@anpr I can help you with this. Please email me at [email protected] and I can add you to our Slack room.

from react_on_rails.

rescribet avatar rescribet commented on July 23, 2024

We're working on restructuring our front-end (splitting into packages), so I can publish these helpers publicly to NPM if that helps

from react_on_rails.

anpr avatar anpr commented on July 23, 2024

I basically copied the code above to my project and it solved the problem (with small adjustments/additions).

Still, I see this being a common requirement, so I'd publish it either as part of the gem or as a separate npm package (I don't really care which of the two).

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

@dzirtusss Please take a look at this one.

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

We're using:

and we don't have many of the headers in

https://gist.github.com/fletcher91/c62b865c6aa9f710531e

Can we abstract this into ReactOnRails?

Reference for Rails: http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf

CC: @alexfedoseev @robwise

from react_on_rails.

justin808 avatar justin808 commented on July 23, 2024

@fletcher91 @anpr @alexfedoseev @dphaener @samnang @dzirtusss: we'd like to know if the headers here: https://gist.github.com/fletcher91/c62b865c6aa9f710531e
should be here: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/libs/requestsManager.js#L33

2016-08-10_12-13-20

from react_on_rails.

dzirtusss avatar dzirtusss commented on July 23, 2024

Actually I think we should not need to include jsonHelper into gem and specifically include json Accept and inContent-Type into headers because it is already included by ??? as follows:

Content-Type: application/json;charset=UTF-8
Accept: application/json, text/plain, */*
Cookie: _rails-react-tutorial_session=...

And everything works fine.

Maybe it will not work with fetch same way but will need to update first from axios to isomorphic-fetch in tutorial.

from react_on_rails.

dzirtusss avatar dzirtusss commented on July 23, 2024

I think it will be ok if we use fetch like:

credentials: 'same-origin',
header: RubyOnRails.authenticityHeader(),

from react_on_rails.

AlexKVal avatar AlexKVal commented on July 23, 2024

Resolved by #517

from react_on_rails.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.