How to Encrypt Request Payload in Reactjs

17,450

Solution 1

after I find out myself and finally I find what I want.

the best way to encrypt data on a payload is to make it encrypted into an object then when the data is received on the controller it is decrypted again

then the most important way when the local strategy in the passport only wants email and password only .. so manipulated again in req.body

in react js

const result = {data : encrypt(values)}
axios.post(`${API}/signin`, result) // I simplify the coding

after that in controller nodejs

app.post(`${api_path}/signin`, 
            validateBody(schemas.loginEncryptAccSchema),
            requireSignIn, //focus in this function
        (req, res, next) => {
            const { user }    = req;
            const { decrypt } = req.query
                  params      = { user, decrypt };
            return console.log('params', params); // i stopped

            const c_account   = new ControllerAccount(params);
            c_account._postSignin(doc => res.status(200).json(doc))
    });

requireSignin function

const requireSignIn       = (req, res, next) => {
        const data     = req.body.data;
        const bytes    = CryptoJS.AES.decrypt(data, `${KEY_CHAIN}`); //i decrypt
              req.body = JSON.parse(bytes.toString(CryptoJS.enc.Utf8)); //then i assign into req.body again
        passport.authenticate('local', { session : false })(req, res, next);
    }

finaaaalyyy xD

Solution 2

You can use JWT encryption and create algorithm that backend can understand/decode when request is handled by the express.

    const jwtDetails = {
        secret: 'your secret', 
        key: 'your key'
    };

    jwtEncrypt.generateJWT(
        jwtDetails,
        payload,
        constants.encryption,
    ).then(token => {
        // use your token on you request payload
    });

On your request payload it will look like this.

data: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmZDJhMDA0Yy0wMTIzLTRmZDctOGEzMi1mY2MzZGJiMmQ1YjAiLCJkYXRhIjp7InB1YmxpYyI6eyJhY2NvdW50IjoiNDAwNyIsInBhc3N3b3JkIjoiMTIzNDU2IiwiYXBpX2tleSI6IkREZTgwZjg0MWVhN2JjOWU3ODk0NmUwYjlkNmQ5YjdlMjAwZWQ1NDY4YSIsInVzZXJfdHlwZSI6WyJBR0VOVCJdfSwiZW5jRGF0YSI6ImQxYmJhNjJhMzE2NWI2MDRhYTM2YTU3ZGZjNTQ2ZTRmIn0sImlhdCI6MTYxNTczMDQ4NCwiZXhwIjoxNjE1NzczNjg0fQ.xVbWKBYJBvpHeYVMqr96nYkLNqkoiOeWRkZ5GmiOi3w

Solution 3

What you can do is

Instead of doing encription and then decription in your frontend side.
You can handle it by your backend 

Simple and secure way is like you just need to pass username and password from 
your front end.

Then check both vaule are not empty.if you get any field empty then return 
error 402 with error message 

If you get both value then first check your user exist or not if not then 
return error 

If your user exist then an then you need to create token from your server side 
and store this token with your user table/document 

When you successfully store your token in users table/model then return 
response with your success message and your token.

Finally you can use your token in frontend. 

You can store this token in localStorage or as cookie in your frontend 

Then in every request which need to be authenticated you can pass your token 
in header of that request and you can verify your token from backend.

If token is not valid then you can simple throw error message that user is not 
authenticated.

Or you can give permission for sending response as per request      

Example :

   //your data and secrete key 
   var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123'); in crypto js    

  then you can pass it to your servere like { data : ciphertext } as payload 

  use that secrete key(like : 'secret key 123') to decrypt your reqest data in your backend side 
Share:
17,450

Related videos on Youtube

Heru Wijayanto
Author by

Heru Wijayanto

Updated on June 04, 2022

Comments

  • Heru Wijayanto
    Heru Wijayanto almost 2 years

    I am working with react js, with additional cryptojs as the encryption, I try to encrypt when requesting data payload ..

    I have done a method such as adding passReqToCallback to my passport but it still does not get results in the console request

    I have added the results to encryption as object {data: result} but it remains unreadable as a payload request instead reads as a data form

    but the results are always 400 bad requests. how is the best way to do it?

    my reactjs code

    const handleSubmit = e => {
            e.preventDefault();
            form.validateFields((err, values) => {
                if (!err) {
                    const postData = {data: encrypt(values)}
                    setSubmit(true);
                    // eslint-disable-next-line no-undef
                    axios.post(`${API}/signin`, postData)
                    .then(response => {
                        return console.log('response', response.data);
    
                        const data = decrypt(response.data);
                        setSubmit(false)
                        if ( _.isString(data) ) {
                            contentNotification({
                                type     : 'error',
                                title    : 'Error',
                                placement: 'topLeft',
                                content  : data
                            })
                        } else {
                            contentNotification({
                                type     : 'success',
                                title    : 'Success',
                                placement: 'topLeft',
                                content  : formatMessage({id: 'LOGIN.SUCCESS'})
                            });
    
                            cookies.set('ckmsbp', response.data);
                            router.push('/');
                        }
                    })
                    .catch(err => {
                        contentNotification({
                            type     : 'error',
                            title    : 'Error',
                            placement: 'topLeft',
                            content  : formatMessage({id: 'LOGIN.ERROR_VALIDATE'})
                        })
                        setSubmit(false)
                        console.error(err);
                    });
                }
            });
        };
    

    here's my routes :

    app.post(`${api_path}/signin`, 
                validateBody(schemas.loginAccSchema),
                requireSignIn,
            (req, res, next) => {
    
                const { user }    = req
                const { decrypt } = req.query
                      params      = { user, decrypt };
    
                const c_account   = new ControllerAccount(params);
                c_account._postSignin(doc => res.status(200).json(doc))
        });
    

    and last my passport

    passport.use(new LocalStrategy({
        usernameField    : 'email',
    passReqToCallback : true
      }, async (req, email, password, done) => {
        // return console.log('req', req);
    
    but do nothing here.. i can't console my request
    
        try{
    ...
    }
    catch{...} 
    

    thanks in advance

    • Prakash Karena
      Prakash Karena over 4 years
      why you are using encryption in you frontend side ??
    • Heru Wijayanto
      Heru Wijayanto over 4 years
      to ensure the data sent is safe
    • Prakash Karena
      Prakash Karena over 4 years
      you have backend in nodejs.Am i right ???
    • Heru Wijayanto
      Heru Wijayanto over 4 years
      yes i have backend in nodejs
    • Prakash Karena
      Prakash Karena over 4 years
      wait i'll give you full answer
  • Prakash Karena
    Prakash Karena over 4 years
    If you have any problem then let me know.
  • Heru Wijayanto
    Heru Wijayanto over 4 years
    honestly most of me have done that, but the point of my question this time is is it possible that the payload request is encrypted and then sent as data and received at the back end?
  • Prakash Karena
    Prakash Karena over 4 years
    you can do that as well.
  • Heru Wijayanto
    Heru Wijayanto over 4 years
    but how, can you help me. I'm stuck there still can't find a way
  • Prakash Karena
    Prakash Karena about 4 years
    as per my knowledge there is not need of extra hard work.Then also you want to use this then i give you solution
  • Prakash Karena
    Prakash Karena about 4 years
    using any library like an example becrypt.you can encrypt your payload with secrete key and use that secrete key to decrypt your palode data
  • Heru Wijayanto
    Heru Wijayanto about 4 years
    do you have any example? i have trying to use encrypt data with crytoJS.. but in the end, the passport js doesnt get the return.. it must be an email and password as payload data..
  • Heru Wijayanto
    Heru Wijayanto about 4 years
    btw.. thanks for the help.. i was found my answer for this problem xD
  • Badi
    Badi almost 2 years
    What I learned in API payloads is I will not recommend to do encryptions, because it requires a lot of process and algorithm to decode encoded values. It will affect the performance of your application during heavy request as it will use a lot of resources in memory and processors.