Search code examples
expressauthenticationcookiesfetch

Set cookie after fetch request response from auth server


I just started learnign about the express library, im developing an app that access restricted info about a user using an Eve Online API, to do this the user is redirected to an authentication page to get an access and refresh token.

Everything works fine until I try to pull the 'refresh_token' from the response and set a cookie with it.

The error:

(node:20600) UnhandledPromiseRejectionWarning: TypeError: res.cookie is not a function

My code:

const url = 'https://login.eveonline.com/v2/oauth/token';
const options = {
    'method':'POST',
    headers:
    {
        'authorization':'Basic '+ process.env.ENV_PASS,
        'Content-Type':'application/x-www-form-urlencoded',
        'host':'login.eveonline.com'
    },
    body:''
}

function send_get_request(req, res){
    options.body =`grant_type=authorization_code&code=${req.query.code}`
    fetch(url,options,{credentials:'include'})
    .then(handle_stream)
    .then(handle_json)
    .then(set_cookie)
    .then(redirect_home)
}

function handle_stream(res){
    return res.json() //handless data stream, returns responce
}
function handle_json(res){
    return res.refresh_token
}
function set_cookie(res){
    return res.cookie('refresh_token','hello')
}
function redirect_home(res){
    res.redirect('http://localhost:3000/home')
}
router.get('/',send_get_request)

I tried breaking the .then() block but still res.cookie doesn't exits. Also tried using credentials but it doesn't work.


Solution

  • Your code contains two variables res: One stands for the response that your middleware sends back to the client, the other stands for the response you are receiving from the fetch operation. Only the handle_stream function operates on the latter, whereas set_cookie and redirect_home operate on the former.

    The last three function are also synchronous and need not be chained with .then. The are invoked synchronously in a function that takes as parameter the json which handle_stream produces asynchronously.

    function send_get_request(req, res){
      options.body =`grant_type=authorization_code&code=${req.query.code}`;
      fetch(url,options,{credentials:'include'})
      .then(handle_stream)
      .then(function(json) {
        var refresh_token = handle_json(json);
        set_cookie(res, refresh_token);
        redirect_home(res);
      });
    }
    

    It is all perhaps easier to understand with the async-await syntax:

    async function send_get_request(req, res){
      options.body =`grant_type=authorization_code&code=${req.query.code}`;
      var response = await fetch(url,options,{credentials:'include'});
      var json = await handle_stream(response);
      var refresh_token = handle_json(json);
      set_cookie(res, refresh_token);
      redirect_home(res);
    }