JWT with Frontity

Hi
I could verify that this plugin can be useful for your customers to authenticate to your React App, using JWT Authentication

1 Like

Could you explain to me how to get the server token?
Thanks !

Look in the USAGE section of their documentation: https://wordpress.org/plugins/jwt-authentication-for-wp-rest-api/

It looks like you have to use the '/jwt-auth/v1/token' with a POST request that contains the username and password.

You can use fetch to do the request. Import it from frontity.

I think I would fetch the token into beforeSSR, right?

const before = async ({ libraries, actions }) => {
  libraries.source.handlers.push(tokenHandler);
  await actions.source.fetch('/fetch-token/')
};
...
actions: {
  theme: {
    beforeSSR: before,
...

that configuration is correct?

Should I be aware of problems with CORS?

Yes, beforeSSR seems a good place to do so.

I don’t know if that plugin takes care of CORS so take a look at it and at the configuration of your WordPress.

Are there any special considerations to take into account if the handler is in beforeSSR?
This is my handler:

import { fetch } from "frontity";

export const tokenHandler = {
  pattern: '/fetch-token/',
  func: async ({ state }) => {  
    const response = await fetch ( urlToFetch, {
      method: 'POST',
      headers: new Headers({
        'Content-Type': 'application/json'
      }),
      body: JSON.stringify({
        username: xxxxxxxxxxxxx,
        password: xxxxxxxxxxxxx
      })
    }
  );

  const data = await response.json();

  Object.assign(state.theme.token, { data });
  }
  }

I’m getting an error:

EventSource's response has a MIME type ("application/json") that is not "text/event-stream". Aborting the connection.

I’m sorry, I told you that beforeSSR was right but this has to be client-side, so this would need to go on afterCSR. CSR stands for client-side rendering.

That seems like a problem not related with Frontity.


By the way, you don’t have to use a handler if you don’t want to. Handlers are only to match a URL with some data in the REST API and the URL /fetch-token/ doesn’t exist. You can just create an action that does the fetch and modifies the state by itself.

I’m not able to find an example on how to do this in the documentation. I need to authenticate in order to see private posts. I’m trying to do a knowledge base with public and private articles and would appreciate any help in a good way to achieve that.

2 Likes

Hi @victorcarvalhosp, below is a function to get the token from the server.
With that token you can do restricted operations, such as viewing private posts.

I hope you find it useful :sunglasses:

fetchToken = () => {
    this.setState({
      isLoading: true,
    })
    fetch(Constants.apiUrl + 'jwt-auth/v1/token', {
      method: 'post',
      headers: new Headers({
        'Content-Type': 'application/json'
      }), 
      body: JSON.stringify({
        username: this.state.username,
        password: this.state.password
      })
    })
    .then(res => res.json())
    .then(data => this.setState({
        token: data.token,
        isLoading: false,
    }))
    .then( console.log('Done!') )
    
    .catch(error => console.log(error))
  }
2 Likes

Can we get the JWT token beforeSSR?

I think the best place to get the token is afterCSR, as @luisherranz says

this code is checked:

...
  actions: {
    theme: {
      afterCSR: async ({ state, libraries, actions }) => {
        if (state.frontity.platform === 'client') {
          if (undefined === state.theme.token) {
            actions.theme.fetchToken();
          }
        }
      },
      fetchToken
    },
  }
..------------------------------------
import { fetch } from 'frontity';

export const fetchToken = async ({ state }) => {
    const res = await fetch(
        `${state.source.api}/jwt-auth/v1/token`, {
            method: 'POST',
            headers: new Headers({
              'Content-Type': 'application/json'
            }),
            body: JSON.stringify({
              "username": state.theme.username,
              "password": state.theme.password
            }),
            redirect: 'follow'
        }
    );
    const body = await res.json();
    state.theme.token = body.token;

}

we can get token in beforeSSR
here is code. how i have done it

fetch(url, {
    method: 'post',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
           username: this.state.username,
           password: this.state.password
    })
  })
   .then(res => res.json())
  .then(data => console.log(data)
  )
  .catch(error => console.log(error))

I guess it depends on your needs.

What do you want to do with the token?

i have used for fetching menus

Ok. Thanks @mehul. Then you only need that in the server, right?

If you expose the username/password on the state it’s going to be sent to the client so that’s not a good idea. It will also be part of your git repository. Even if the repository is not public, that’s also not a good idea.

A common approach to add sensible data to an app is to use environment variables. You have a lot of info about how to do so in this topic: How to read Environment Variables

2 Likes

A post was split to a new topic: Protected routes with Frontity

could you show me how did this please i am trying to get custom post type

HI @hugsaf2132

In order to help with your issue, can you please provide the info suggested here?

The more info you provide the better. Providing a repo or code-sandbox with your code is especially helpful to find solutions of technical issues with specific code

How would I proceed with this? I’d like to try it out.

Here is a very basic implementation:

2 Likes