Защищенный маршрут, возвращающий неверно сформированный запрос.json() для реагирования на интерфейс

#express #fetch

Вопрос:

Я пытаюсь сделать запрос на получение защищенного маршрута в своем приложении Express. Маршрут работает нормально, когда запрос сделан почтальоном, я получаю отправленный ответ. Но когда я пытаюсь выполнить запрос на извлечение из интерфейса, я получаю SyntaxError: Unexpected token A in JSON at position 0 .

Запрос на извлечение из интерфейса

 export const getProtectedMessage = async (token) => {
  const URI = 'http://localhost:3001'; //TODO save root uri to environment variable
  const bearer = 'Bearer '   token;
  return fetch(`${URI}/me`, {
    method: 'GET',
    withCredentials: true,
    credentials: 'include',
    headers: {
      'Authorization': bearer,
      'Content-Type': 'application/json',
      'Cache-Control': 'no-cache'
    }
  })
    .then(handleErrors)
    .then((res) => res.json())
    .catch((err) => {
      console.error(err);
    });
};

 

Точка входа для экспресс-приложения index.js

 import dotenv from 'dotenv';
import express from 'express';
import morgan from 'morgan';
import cors from 'cors';
import routes from './routes/index.js';
import db from './db/index.js';

dotenv.config();
db(process.env.DB_NAME);

const PORT = process.env.PORT || 3001;

const app = express();
app.use(express.json());
app.use(cors({ credentials: true, origin: 'http://localhost:3000' }));
app.use(morgan('dev'));

app.use(routes);

app.get('*', (req, res) => {
  res.sendStatus(404);
});
app.listen(process.env.PORT, () => {
  console.log(`app listening on port ${PORT}`);
});
 

Маршруты

 import express from 'express';
import * as auth from '../controllers/auth.js';
import expressjwt from 'express-jwt';
import dotenv from 'dotenv';
dotenv.config();

const router = express.Router();

const jwtCheck = expressjwt({
  secret: process.env.SECRET_KEY,
  algorithms: ['sha1', 'RS256', 'HS256']
});

router.post('/sign-up', auth.signUp);
router.post('/sign-in', auth.signIn);
router.get('/me', jwtCheck, auth.profile);

export default router;
 

Контроллер для защищенного маршрута

 
export function profile(req, res) {
  res.status(200).send('A secret resource - only for authenticated users');
}

 

Комментарии:

1. Вы отправляете строку( res.status(200).send('A secret resource - only for authenticated users'); ) со своего сервера, и на стороне интерфейса вы пытаетесь проанализировать ее в json( res.json() . что является ошибкой.

2. Попробуйте это — res.status(200).json({screct:"##########"})

3. @GulamHussain Спасибо! Я обновил свой ответ 🙂

Ответ №1:

В конце концов ошибка заключалась в том, как я отправлял ответ. Может быть, есть более подходящий способ сделать это, но замена контроллера на следующий сработала.

 export function profile(req, res) {
  // res.status(200).send('A secret resource - only for authenticated users'); // WRONG
  res.status(200).json('Resource only for authenticated users'); // works!
}
 

Еще одна вещь, также рекомендуется проверять заголовок приложения в запросе на выборку. Иногда вы не знаете, что получаете от бэкенда, может быть json, может быть текст.

 export const getProtectedMessage = async (token) => {
  const URI = 'http://localhost:3001'; //TODO save root uri to environment variable
  const bearer = 'Bearer '   token;
  return fetch(`${URI}/me`, {
    method: 'GET',
    withCredentials: true,
    credentials: 'include',
    headers: {
      Authorization: bearer,
      'Content-Type': 'application/json',
      'Cache-Control': 'no-cache'
    }
  })
    .then(handleErrors)
    .then((res) => {
      const contentType = res.headers.get('Content-Type').split(';')[0];
      if (contentType === 'application/json') {
        return res.json();
      }
      console.log(contentType);
      if (contentType === 'text/html') {
        return res.text();
      }
    })
    .catch((err) => {
      console.error(err);
    });
};